1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sourceforge.domian.test.benchmark;
17
18
19 import java.math.BigDecimal;
20 import java.math.RoundingMode;
21 import java.util.Collection;
22 import java.util.logging.Logger;
23
24 import net.sourceforge.domian.entity.AbstractUUIDEntity;
25 import net.sourceforge.domian.repository.HashSetRepository;
26 import net.sourceforge.domian.repository.InMemoryAndXStreamXmlFileRepository;
27 import net.sourceforge.domian.repository.InMemoryRepository;
28 import net.sourceforge.domian.repository.NotImplementedRepository;
29 import net.sourceforge.domian.repository.NullRepository;
30 import net.sourceforge.domian.repository.PartitionRepository;
31 import net.sourceforge.domian.repository.PersistentRepository;
32 import net.sourceforge.domian.repository.Repository;
33 import net.sourceforge.domian.repository.UnsupportedRepository;
34 import net.sourceforge.domian.repository.XStreamXmlFilePerEntityRepository;
35 import net.sourceforge.domian.specification.Specification;
36 import static net.sourceforge.domian.specification.SpecificationFactory.instancesOfType;
37 import static net.sourceforge.domian.specification.SpecificationFactory.isFalse;
38 import static net.sourceforge.domian.specification.SpecificationFactory.isTrue;
39 import static net.sourceforge.domian.util.InstrumentationUtils.prettyPrintLargeNumber;
40 import net.sourceforge.domian.util.StopWatch;
41 import static net.sourceforge.domian.util.StopWatch.print;
42
43
44 abstract class AbstractQueenPuzzle extends AbstractUUIDEntity {
45
46 private final Logger log = Logger.getLogger(AbstractQueenPuzzle.class.getName());
47
48 enum RepositoryType {
49 UNSUPPORTED,
50 NOT_IMPLEMENTED,
51 NULL,
52 HASHSET,
53 PARTITIONED_HASHSET,
54 INMEMORY,
55 PARTITIONED_INMEMORY,
56 HIGH_SCALE_LIB_HASH_SET,
57 PARTITIONED_HIGH_SCALE_LIB_HASH_SET,
58 XSTREAM,
59 PARTITIONED_XSTREAM,
60 INMEMORY_XSTREAM,
61 PARTITIONED_INMEMORY_XSTREAM,
62 DB4O,
63 PARTITIONED_DB4O,
64 INMEMORY_DB4O,
65 PARTITIONED_INMEMORY_DB4O
66 }
67
68 static final Specification<QueenPuzzleConstellation> queenPuzzleConstellationsThatInherentlySolvesTheQueenPuzzle = new QueenPuzzleSpecification();
69 static final Specification<QueenPuzzleConstellation> unProcessedQueenPuzzleConstellations = instancesOfType(QueenPuzzleConstellation.class).where("processed", isFalse());
70 static final Specification<QueenPuzzleConstellation> processedQueenPuzzleConstellations = instancesOfType(QueenPuzzleConstellation.class).where("processed", isTrue());
71 static final Specification<QueenPuzzleConstellation> queenPuzzleConstellationsThatIsProcessedAndMarkedAsToSolveTheQueenPuzzle = instancesOfType(QueenPuzzleConstellation.class).where("solvesQueenPuzzle", isTrue());
72
73
74
75 protected long numberOfConstellations;
76 protected int numberOfWorkers;
77 protected long logInterval;
78
79 protected SequentialQueenPuzzle.RepositoryType repositoryType;
80 protected Collection<? extends QueenPuzzleConstellation> successfulQueenPuzzleConstellations;
81
82 AbstractQueenPuzzle(final SequentialQueenPuzzle.RepositoryType repositoryType,
83 final long numberOfConstellations,
84 final int numberOfWorkers,
85 final long logInterval) {
86 this.repositoryType = repositoryType;
87 this.numberOfConstellations = numberOfConstellations;
88 this.numberOfWorkers = numberOfWorkers;
89 this.logInterval = logInterval;
90
91 solvePuzzle();
92
93 }
94
95 abstract void solvePuzzle();
96
97 protected Repository<QueenPuzzleConstellation> createRepository(final RepositoryType repositoryType) {
98 switch (repositoryType) {
99 case UNSUPPORTED:
100 return new UnsupportedRepository<QueenPuzzleConstellation>();
101 case NOT_IMPLEMENTED:
102 return new NotImplementedRepository<QueenPuzzleConstellation>();
103 case NULL:
104 return new NullRepository<QueenPuzzleConstellation>();
105 case HASHSET:
106 return new HashSetRepository<QueenPuzzleConstellation>();
107 case PARTITIONED_HASHSET:
108 return new HashSetRepository<QueenPuzzleConstellation>().makePartition();
109 case INMEMORY:
110 return new InMemoryRepository<QueenPuzzleConstellation>();
111 case PARTITIONED_INMEMORY:
112 return new InMemoryRepository<QueenPuzzleConstellation>().makePartition();
113
114
115 case XSTREAM:
116 return new XStreamXmlFilePerEntityRepository<QueenPuzzleConstellation>("queen-puzzle");
117 case PARTITIONED_XSTREAM:
118 return new XStreamXmlFilePerEntityRepository<QueenPuzzleConstellation>("queen-puzzle").makePartition();
119 case INMEMORY_XSTREAM:
120 return new InMemoryAndXStreamXmlFileRepository<QueenPuzzleConstellation>("queen-puzzle");
121 case PARTITIONED_INMEMORY_XSTREAM:
122 return new InMemoryAndXStreamXmlFileRepository<QueenPuzzleConstellation>("queen-puzzle").makePartition();
123
124
125
126
127
128 default:
129 throw new IllegalArgumentException("Unknown repository type");
130 }
131 }
132
133
134 protected void addOneWellKnownSuccessfulQueenPuzzleConstellationInto(final Repository<QueenPuzzleConstellation> repo) {
135 repo.put(new QueenPuzzleConstellation(new ChessPiecePlacing(0),
136 new ChessPiecePlacing(12),
137 new ChessPiecePlacing(23),
138 new ChessPiecePlacing(29),
139 new ChessPiecePlacing(34),
140 new ChessPiecePlacing(46),
141 new ChessPiecePlacing(49),
142 new ChessPiecePlacing(59)));
143 }
144
145
146 protected void generateQueenPuzzleConstellationsAndPutInto(final Repository repo) {
147 StopWatch stopWatch = new StopWatch().start();
148
149
150 new RandomPermutationQueenPuzzleConstellationFactory(this.numberOfConstellations, this.logInterval).generateAndPopulate(repo);
151
152
153
154
155
156
157 stopWatch.stop();
158 System.out.println(prettyPrintLargeNumber(this.numberOfConstellations) + " chess piece constellations created and added to repo, time consumed " + stopWatch.toString());
159 BigDecimal averageTimeForEachPiece = new BigDecimal(stopWatch.getElapsedTime()).divide(new BigDecimal(this.numberOfConstellations), 3, RoundingMode.HALF_UP);
160 System.out.println("Average time for each piece: " + averageTimeForEachPiece.divide(new BigDecimal(1000000)));
161 System.out.println("Number of pieces per second: " + prettyPrintLargeNumber(this.numberOfConstellations * 1000000000 / stopWatch.getElapsedTime()));
162 System.out.println();
163 }
164
165 protected void doPrintProcessStatistics(final long elapsedTimeInNanos, final long numberOfConstellations) {
166 System.out.println();
167 System.out.println(prettyPrintLargeNumber(numberOfConstellations) + " chess piece constellations processed, time consumed " + print(elapsedTimeInNanos));
168 final BigDecimal averageTimeForEachPiece = new BigDecimal(elapsedTimeInNanos).divide(new BigDecimal(numberOfConstellations), 3, RoundingMode.HALF_UP);
169 System.out.println("Average time for each piece: " + print(averageTimeForEachPiece.longValue()));
170 System.out.println("Number of pieces per second: " + prettyPrintLargeNumber(numberOfConstellations * 1000000000 / elapsedTimeInNanos));
171 }
172
173 protected void doRepartition(final PartitionRepository<QueenPuzzleConstellation> repo) {
174 StopWatch stopWatch = new StopWatch().start();
175 repo.repartition();
176 System.out.println();
177 System.out.println("Repartition Service finished, time consumed " + stopWatch);
178 BigDecimal averageTimeForEachPiece = new BigDecimal(stopWatch.getElapsedTime()).divide(new BigDecimal(this.numberOfConstellations), 3, RoundingMode.HALF_UP);
179 System.out.println("Average time for each piece: " + print(averageTimeForEachPiece.longValue()));
180 System.out.println("Number of pieces per second: " + prettyPrintLargeNumber(this.numberOfConstellations * 1000000000 / stopWatch.getElapsedTime()));
181 }
182
183 protected void doPersist(final PersistentRepository<QueenPuzzleConstellation> repo) {
184 StopWatch stopWatch = new StopWatch().start();
185 repo.persist();
186 System.out.println();
187 System.out.println("Persistence Service finished, time consumed " + stopWatch);
188 BigDecimal averageTimeForEachPiece = new BigDecimal(stopWatch.getElapsedTime()).divide(new BigDecimal(this.numberOfConstellations), 3, RoundingMode.HALF_UP);
189 System.out.println("Average time for each piece: " + print(averageTimeForEachPiece.longValue()));
190 System.out.println("Number of pieces per second: " + prettyPrintLargeNumber(this.numberOfConstellations * 1000000000 / stopWatch.getElapsedTime()));
191 }
192
193 protected void doResultSearch(final Repository<QueenPuzzleConstellation> repo) {
194 StopWatch stopWatch = new StopWatch().start();
195 this.successfulQueenPuzzleConstellations = repo.findAll(queenPuzzleConstellationsThatIsProcessedAndMarkedAsToSolveTheQueenPuzzle);
196 final int numberOfSuccessfulQueenPuzzleConstellations = this.successfulQueenPuzzleConstellations.size();
197 stopWatch.stop();
198 System.out.println();
199 if (numberOfSuccessfulQueenPuzzleConstellations > 1) {
200 System.err.println("INFO [Domian]: WOW, there is actually randomly generated a successful queen puzzle constellation! You must be the luckiest person on earth!!");
201 }
202 if (numberOfSuccessfulQueenPuzzleConstellations == 0) {
203 System.out.println("No chess piece constellations solves the Queen Puzzle");
204 } else {
205 System.out.println(numberOfSuccessfulQueenPuzzleConstellations + " chess piece constellations solves the Queen Puzzle, first one is " + this.successfulQueenPuzzleConstellations.iterator().next());
206 }
207 System.out.println("Search time: " + stopWatch);
208 stopWatch.reset();
209 }
210
211 protected void doCompletionControl(final Repository<QueenPuzzleConstellation> repo) {
212 StopWatch stopWatch = new StopWatch().start();
213 final Collection<QueenPuzzleConstellation> unprocessedConstellations = repo.findAll(unProcessedQueenPuzzleConstellations);
214 final int numberOfUnprocessedConstellations = unprocessedConstellations.size();
215 stopWatch.stop();
216 System.out.println();
217 if (numberOfUnprocessedConstellations > 0) {
218 log.warning("There are unprocessed constellations present!");
219 }
220 System.out.println(numberOfUnprocessedConstellations + " chess piece constellations NOT processed");
221 System.out.println("Search time: " + stopWatch);
222 }
223 }