1 /*
2 * Copyright 2006-2010 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sourceforge.domian.test.benchmark;
17
18
19 import java.text.SimpleDateFormat;
20 import java.util.Collection;
21 import java.util.Date;
22 import java.util.Iterator;
23
24 import net.sourceforge.domian.repository.PartitionRepository;
25 import net.sourceforge.domian.repository.PersistenceDefinition;
26 import net.sourceforge.domian.repository.PersistentRepository;
27 import net.sourceforge.domian.repository.Repository;
28 import static net.sourceforge.domian.specification.SpecificationFactory.all;
29 import static net.sourceforge.domian.test.benchmark.QueenPuzzleUtils.conditionalLogging;
30 import net.sourceforge.domian.util.StopWatch;
31
32
33 /**
34 * An amusing little computing task involving (possible) vast numbers of repository inserts, updates, and search.
35 * <p/>
36 * In detail, it consists of:
37 * <ol>
38 * <li/>Generating random chess piece constellations consisting of 8 pieces, disguised as entity objects; adding them to a repository
39 * <li/>A batch processing task, iterating through all constellations, doing a little check, with a conditional update
40 * <li/>A search task for all constellations solving the queen puzzle
41 * <li/>A completion control search task for all constellations not processed (should be none)
42 * </ol>
43 * <p/>
44 * The batch processing task tries to solve the infamous "Queen Puzzle" which seeks to find all possible chess queen piece constellations
45 * where none of the queens are threatened by one of the other queens.
46 * A standard 8 x 8 chess board and 8 queen pieces are hard-coded.
47 * Possible sequences of queens are staggering 64^8 = 281.474.976.710.656 (over 280 trillions!)
48 */
49 final class SequentialQueenPuzzle extends AbstractQueenPuzzle {
50
51 SequentialQueenPuzzle(final RepositoryType repositoryType, final Long numberOfConstellations, final long logInterval) {
52 super(repositoryType, numberOfConstellations, 1, logInterval);
53 }
54
55 Collection<? extends QueenPuzzleConstellation> getSuccessfulQueenPuzzleConstellations() {
56 return this.successfulQueenPuzzleConstellations;
57 }
58
59 void solvePuzzle() {
60 System.out.println();
61 System.out.println("Solving the \"Queen Puzzle\"... [start time: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS").format(new Date()) + "]");
62 System.out.println();
63
64 /****** The repository to torment ******/
65 final Repository<QueenPuzzleConstellation> repo = createRepository(this.repositoryType);
66 if (repo instanceof PersistentRepository) {
67 if (((PersistentRepository) repo).getPersistenceDefinition().supportsAsynchronousPersistence()) {
68 repo.remove(all(QueenPuzzleConstellation.class));
69 ((PersistentRepository) repo).persist();
70 }
71 }
72
73 final StopWatch stopWatch = new StopWatch().start();
74
75 /* Add partition if possible */
76 if (repo instanceof PartitionRepository) {
77 //((PartitionRepository) repo).addPartitionFor(queenPuzzleConstellationsThatInherentlySolvesTheQueenPuzzle); // This would of course be the fastest and smartest thing to do - but kind of violates the purpose of this execution...
78 ((PartitionRepository<QueenPuzzleConstellation>) repo).addPartitionFor(queenPuzzleConstellationsThatIsProcessedAndMarkedAsToSolveTheQueenPuzzle, "approved-queenpuzzle-constellations");
79 ((PartitionRepository<QueenPuzzleConstellation>) repo).addPartitionFor(unProcessedQueenPuzzleConstellations, "unprocessed-queenpuzzle-constellations");
80 }
81
82 /****** Adding correct constellation just to if everything seems to work... ******/
83 addOneWellKnownSuccessfulQueenPuzzleConstellationInto(repo);
84
85 /****** The data generator ******/
86 generateQueenPuzzleConstellationsAndPutInto(repo);
87
88 /* Search the repo and check each constellation if they support the queen puzzle constraints... */
89 /* Update each constellation with processing result... */
90 final Iterator<? extends QueenPuzzleConstellation> allUnprocessedConstellations = repo.iterate(unProcessedQueenPuzzleConstellations);
91 System.out.println("Processing unprocessed chess piece constellations...");
92 long numberOfConstellationsFound = 0;
93 while (allUnprocessedConstellations.hasNext()) {
94 QueenPuzzleConstellation queenPuzzleConstellation = allUnprocessedConstellations.next();
95 queenPuzzleConstellation.setSolvesQueenPuzzle(queenPuzzleConstellationsThatInherentlySolvesTheQueenPuzzle.isSatisfiedBy(queenPuzzleConstellation));
96 /* ConcurrentModificationException of course...
97 if (repo instanceof PartitionedHashSetRepository) {
98 ((PartitionedHashSetRepository) repo).rePartition(queenPuzzleConstellation);
99 } */
100 conditionalLogging(logInterval, ++numberOfConstellationsFound, stopWatch, queenPuzzleConstellation, "processed so far...");
101 }
102 doPrintProcessStatistics(stopWatch.getElapsedTime(), this.numberOfConstellations);
103
104 /****** Repartition if necessary ******/
105 /*if (repo instanceof PartitionedHashSetRepository) {
106 doRepartition((PartitionedHashSetRepository) repo);
107 }*/
108
109 /****** The result search task ******/
110 doResultSearch(repo);
111
112 /****** The completion control task ******/
113 doCompletionControl(repo);
114
115 System.out.println();
116 System.out.println("Overall time: " + stopWatch);
117 }
118 }