1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.statistics;
23
24 import java.io.IOException;
25 import java.io.ObjectInput;
26 import java.io.ObjectOutput;
27 import java.util.Iterator;
28 import java.util.Map;
29 import java.util.TreeMap;
30 import java.util.Map.Entry;
31
32 import net.grinder.common.AbstractTestSemantics;
33 import net.grinder.common.Test;
34
35
36
37
38
39
40
41
42
43
44
45 public final class TestStatisticsMap implements java.io.Externalizable {
46
47
48
49
50 private static final long serialVersionUID = 5L;
51
52 private final transient StatisticsSetFactory m_statisticsSetFactory;
53
54
55
56
57
58 private final Map<Test, StatisticsSet> m_data =
59 new TreeMap<Test, StatisticsSet>();
60
61
62
63
64
65
66 public TestStatisticsMap(StatisticsSetFactory statisticsSetFactory) {
67 m_statisticsSetFactory = statisticsSetFactory;
68 }
69
70
71
72
73 public TestStatisticsMap() {
74
75
76 this(
77 StatisticsServicesImplementation.getInstance().getStatisticsSetFactory());
78 }
79
80
81
82
83
84
85
86 public void put(Test test, StatisticsSet statistics) {
87 if (!(statistics instanceof StatisticsSetImplementation)) {
88 throw new AssertionError(
89 "StatisticsSet implementation not supported");
90 }
91
92 synchronized (this) {
93 m_data.put(test, statistics);
94 }
95 }
96
97
98
99
100
101
102
103 public int size() {
104 synchronized (this) {
105 return m_data.size();
106 }
107 }
108
109
110
111
112
113
114
115 public void add(TestStatisticsMap other) {
116 synchronized (other) {
117 for (Entry<Test, StatisticsSet> othersEntry : other.m_data.entrySet()) {
118 final StatisticsSet statistics;
119
120 synchronized (this) {
121 final StatisticsSet existingStatistics =
122 m_data.get(othersEntry.getKey());
123
124 if (existingStatistics == null) {
125 statistics = m_statisticsSetFactory.create();
126 put(othersEntry.getKey(), statistics);
127 }
128 else {
129 statistics = existingStatistics;
130 }
131 }
132
133 statistics.add(othersEntry.getValue());
134 }
135 }
136 }
137
138
139
140
141
142
143 public TestStatisticsMap reset() {
144 final TestStatisticsMap result =
145 new TestStatisticsMap(m_statisticsSetFactory);
146
147 new ForEach() {
148 public void next(Test test, StatisticsSet statistics) {
149 final StatisticsSet snapshot;
150
151 synchronized (statistics) {
152 snapshot = statistics.snapshot();
153 statistics.reset();
154 }
155
156 if (!snapshot.isZero()) {
157 result.put(test, snapshot);
158 }
159 }
160 }
161 .iterate();
162
163 return result;
164 }
165
166
167
168
169
170
171 public StatisticsSet nonCompositeStatisticsTotals() {
172 final StatisticsSet result = m_statisticsSetFactory.create();
173
174 new ForEach() {
175 public void next(Test test, StatisticsSet statistics) {
176 if (!statistics.isComposite()) {
177 result.add(statistics);
178 }
179 }
180 }
181 .iterate();
182
183 return result;
184 }
185
186
187
188
189
190
191 public StatisticsSet compositeStatisticsTotals() {
192 final StatisticsSet result = m_statisticsSetFactory.create();
193
194 new ForEach() {
195 public void next(Test test, StatisticsSet statistics) {
196 if (statistics.isComposite()) {
197 result.add(statistics);
198 }
199 }
200 }
201 .iterate();
202
203 return result;
204 }
205
206
207
208
209
210
211
212
213 public boolean equals(Object o) {
214 if (o == this) {
215 return true;
216 }
217
218 if (o == null || o.getClass() != TestStatisticsMap.class) {
219 return false;
220 }
221
222 final TestStatisticsMap otherMap = (TestStatisticsMap)o;
223
224 if (m_data.size() != otherMap.m_data.size()) {
225 return false;
226 }
227
228 final Iterator<Entry<Test, StatisticsSet>> iterator =
229 m_data.entrySet().iterator();
230 final Iterator<Entry<Test, StatisticsSet>> otherIterator =
231 otherMap.m_data.entrySet().iterator();
232
233 while (iterator.hasNext()) {
234 final Entry<Test, StatisticsSet> entry = iterator.next();
235 final Entry<Test, StatisticsSet> otherEntry = otherIterator.next();
236
237 if (!entry.getKey().equals(otherEntry.getKey()) ||
238 !entry.getValue().equals(otherEntry.getValue())) {
239 return false;
240 }
241 }
242
243 return true;
244 }
245
246
247
248
249
250
251
252
253
254 public int hashCode() {
255 return super.hashCode();
256 }
257
258
259
260
261
262
263
264 public String toString() {
265 final StringBuilder result = new StringBuilder();
266
267 result.append("TestStatisticsMap = {");
268
269 new ForEach() {
270 public void next(Test test, StatisticsSet statisticsSet) {
271 result.append("(");
272 result.append(test);
273 result.append(", ");
274 result.append(statisticsSet);
275 result.append(")");
276 }
277 }
278 .iterate();
279
280 result.append("}");
281
282 return result.toString();
283 }
284
285
286
287
288
289
290
291 public void writeExternal(ObjectOutput out) throws IOException {
292
293 synchronized (this) {
294 out.writeInt(m_data.size());
295
296 for (Entry<Test, StatisticsSet> entry : m_data.entrySet()) {
297 out.writeInt(entry.getKey().getNumber());
298
299
300
301 m_statisticsSetFactory.writeStatisticsExternal(
302 out, (StatisticsSetImplementation)entry.getValue());
303 }
304 }
305 }
306
307
308
309
310
311
312
313
314 public void readExternal(ObjectInput in) throws IOException {
315
316 final int n = in.readInt();
317
318 m_data.clear();
319
320 for (int i = 0; i < n; i++) {
321 m_data.put(new LightweightTest(in.readInt()),
322 m_statisticsSetFactory.readStatisticsExternal(in));
323 }
324 }
325
326
327
328
329 private static final class LightweightTest extends AbstractTestSemantics {
330 private final int m_number;
331
332 public LightweightTest(int number) {
333 m_number = number;
334 }
335
336 public int getNumber() {
337 return m_number;
338 }
339
340 public String getDescription() {
341 return "";
342 }
343 }
344
345
346
347
348 public abstract class ForEach {
349
350
351
352 public void iterate() {
353 synchronized (TestStatisticsMap.this) {
354 for (Entry<Test, StatisticsSet> entry : m_data.entrySet()) {
355 next(entry.getKey(), entry.getValue());
356 }
357 }
358 }
359
360
361
362
363
364
365
366 protected abstract void next(Test test, StatisticsSet statistics);
367 }
368 }