KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > prevayler > demos > scalability > ScalabilityTestRun


1 package org.prevayler.demos.scalability;
2
3 import java.util.*;
4 import java.text.DecimalFormat JavaDoc;
5 import org.prevayler.foundation.*;
6
7 /** Represents a single run of a scalability test. To understand the implementation of this class, you must be familiar with Prevayler's Scalability Test (run org.prevayler.test.scalability.ScalabilityTest).
8 */

9 abstract class ScalabilityTestRun {
10
11     static private final long ROUND_DURATION_MILLIS = 1000 * 20;
12
13     private final ScalabilityTestSubject subject;
14     protected final int numberOfObjects;
15
16     private double bestRoundOperationsPerSecond;
17     private int bestRoundThreads;
18
19     private final List connectionCache = new LinkedList();
20
21     private long operationCount = 0;
22     private long lastOperation = 0;
23     private boolean isRoundFinished;
24     private int activeRoundThreads = 0;
25
26
27     /** @return Example: "123.12 operations/second (12 threads)".
28     */

29     public String JavaDoc getResult() {
30         return toResultString(bestRoundOperationsPerSecond, bestRoundThreads);
31     }
32
33
34     public double getOperationsPerSecond() {
35         return bestRoundOperationsPerSecond;
36     }
37
38
39     protected ScalabilityTestRun(ScalabilityTestSubject subject, int numberOfObjects, int minThreads, int maxThreads) {
40         if (minThreads > maxThreads) throw new IllegalArgumentException JavaDoc("The minimum number of threads cannot be greater than the maximum number.");
41         if (minThreads < 1) throw new IllegalArgumentException JavaDoc("The minimum number of threads cannot be smaller than one.");
42
43         this.subject = subject;
44         this.numberOfObjects = numberOfObjects;
45
46         out("\n\n========= Running " + name() + " (" + (maxThreads - minThreads + 1) + " rounds). Subject: " + subject.name() + "...");
47         prepare();
48
49         out("Each round will take approx. " + ROUND_DURATION_MILLIS / 1000 + " seconds to run...");
50         performTest(minThreads, maxThreads);
51         out("\n----------- BEST ROUND: " + getResult());
52     }
53
54     protected void prepare() {
55         subject.replaceAllRecords(numberOfObjects);
56         System.gc();
57     }
58
59
60     /** @return The name of the test to be executed. Example: "Prevayler Query Test".
61     */

62     protected abstract String JavaDoc name();
63
64
65     private void performTest(int minThreads, int maxThreads) {
66
67         int threads = minThreads;
68         while (threads <= maxThreads) {
69             double operationsPerSecond = performRound(threads);
70
71             if (operationsPerSecond > bestRoundOperationsPerSecond) {
72                 bestRoundOperationsPerSecond = operationsPerSecond;
73                 bestRoundThreads = threads;
74             }
75
76             threads++;
77         }
78     }
79
80
81     /** @return The number of operations the test managed to execute per second with the given number of threads.
82     */

83     private double performRound(int threads) {
84         long initialOperationCount = operationCount;
85         StopWatch stopWatch = StopWatch.start();
86
87         startThreads(threads);
88         sleep();
89         stopThreads();
90
91         double secondsEllapsed = stopWatch.secondsEllapsed();
92         double operationsPerSecond = (operationCount - initialOperationCount) / secondsEllapsed;
93
94         out("\nMemory used: " + Runtime.getRuntime().totalMemory());
95         out("Seconds ellapsed: " + secondsEllapsed);
96         out("--------- Round Result: " + toResultString(operationsPerSecond, threads));
97
98         return operationsPerSecond;
99     }
100
101
102     private void startThreads(int threads) {
103         isRoundFinished = false;
104
105         int i = 1;
106         while(i <= threads) {
107             startThread(lastOperation + i, threads);
108             i++;
109         }
110     }
111
112
113     private void startThread(final long startingOperation, final int operationIncrement) {
114         (new Thread JavaDoc() {
115             public void run() {
116                 try {
117                     Object JavaDoc connection = acquireConnection();
118
119                     long operation = startingOperation;
120                     while (!isRoundFinished) {
121                         executeOperation(connection, operation);
122                         operation += operationIncrement;
123                     }
124
125                     synchronized (connectionCache) {
126                         connectionCache.add(connection);
127                         operationCount += (operation - startingOperation) / operationIncrement;
128                         if (lastOperation < operation) lastOperation = operation;
129                         activeRoundThreads--;
130                     }
131
132                 } catch (OutOfMemoryError JavaDoc err) {
133                     outOfMemory();
134                 }
135             }
136         }).start();
137
138         activeRoundThreads++;
139     }
140
141
142     protected abstract void executeOperation(Object JavaDoc connection, long operation);
143
144
145     private Object JavaDoc acquireConnection() {
146         synchronized (connectionCache) {
147             return connectionCache.isEmpty()
148                 ? subject.createTestConnection()
149                 : connectionCache.remove(0);
150         }
151     }
152
153
154     private void stopThreads() {
155         isRoundFinished = true;
156         while (activeRoundThreads != 0) {
157             Thread.yield();
158         }
159     }
160
161
162     static private String JavaDoc toResultString(double operationsPerSecond, int threads) {
163         String JavaDoc operations = new DecimalFormat JavaDoc("0.00").format(operationsPerSecond);
164         return "" + operations + " operations/second (" + threads + " threads)";
165     }
166
167     static void outOfMemory() {
168         System.gc();
169         out(
170             "\n\nOutOfMemoryError.\n" +
171             "===========================================================\n" +
172             "The VM must be started with a sufficient maximum heap size.\n" +
173             "Example for Linux and Windows: java -Xmx512000000 ...\n\n"
174         );
175     }
176
177     static private void sleep() {
178         try {
179             Thread.sleep(ROUND_DURATION_MILLIS);
180         } catch (InterruptedException JavaDoc ix) {
181             throw new RuntimeException JavaDoc("Unexpected InterruptedException.");
182         }
183     }
184
185     
186     static private void out(Object JavaDoc obj) {
187         System.out.println(obj);
188     }
189 }
190
Popular Tags