ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/DequeBash.java
Revision: 1.1
Committed: Mon May 2 19:19:38 2005 UTC (19 years ago) by dl
Branch: MAIN
Log Message:
Put misc performance tests into CVS

File Contents

# Content
1 /*
2 * Written by Josh Bloch of Google Inc. and released to the public domain,
3 * as explained at http://creativecommons.org/licenses/publicdomain.
4 */
5
6 import java.util.*;
7 import java.io.*;
8
9 /**
10 * Interface-based Deque tester. This test currently makes three
11 * assumptions about the implementation under test:
12 *
13 * 1) It has no size limitation.
14 * 2) It implements Serializable.
15 * 3) It has a conventional (Collection) constructor.
16 *
17 * All of these assumptions could be relaxed.
18 */
19 public class DequeBash {
20 static int seed = 7;
21 static int nextTail = 0;
22 static int nextHead = -1;
23 static int size() { return nextTail - nextHead - 1; }
24
25
26 static int random(int bound) {
27 int x = seed;
28 int t = (x % 127773) * 16807 - (x / 127773) * 2836;
29 seed = (t > 0)? t : t + 0x7fffffff;
30 return (t & 0x7fffffff) % bound;
31 }
32
33 static int random() {
34 int x = seed;
35 int t = (x % 127773) * 16807 - (x / 127773) * 2836;
36 seed = (t > 0)? t : t + 0x7fffffff;
37 return (t & 0x7fffffff);
38 }
39
40 public static void main(String args[]) throws Exception {
41 Class cls = Class.forName(args[0]);
42 int n = 1000000;
43
44 for (int j = 0; j < 3; ++j) {
45 Deque<Integer> deque = (Deque<Integer>) cls.newInstance();
46 nextTail = 0;
47 nextHead = -1;
48 long start = System.currentTimeMillis();
49 mainTest(deque, n);
50 long end = System.currentTimeMillis();
51 System.out.println("Time: " + (end - start) + "ms");
52 if (deque.isEmpty()) System.out.print(" ");
53 }
54
55 }
56
57 static void mainTest(Deque<Integer> deque, int n) throws Exception {
58 /*
59 * Perform a random sequence of operations, keeping contiguous
60 * sequence of integers on the deque.
61 */
62 for (int i = 0; i < n; i++) {
63 sizeTests(deque);
64 randomOp(deque);
65
66 // Test iterator occasionally
67 if ((i & 1023) == 0)
68 testIter(deque);
69
70 // Test serialization and copying
71 if ((i & 4095) == 0) {
72 testEqual(deque, deepCopy(deque));
73 testEqual(deque, (Deque<Integer>) deque.getClass().
74 getConstructor(Collection.class).newInstance(deque));
75 }
76
77 // Test fancy removal stuff once in a blue moon
78 if ((i & 8191) == 0)
79 testRemove(deque);
80
81 }
82
83 // Stupid tests for clear, toString
84 deque.clear();
85 testEmpty(deque);
86 Collection<Integer> c = Arrays.asList(1, 2, 3);
87 deque.addAll(c);
88 if (!deque.toString().equals("[1, 2, 3]"))
89 throw new Exception("Deque.toString(): " + deque.toString());
90 }
91
92 static void testIter(Deque<Integer> deque) throws Exception {
93 int next = nextHead + 1;
94 int count = 0;
95 for (int j : deque) {
96 if (j != next++)
97 throw new Exception("Element "+ j + " != " + (next-1));
98 count++;
99 }
100 if (count != size())
101 throw new Exception("Count " + count + " != " + size());
102 }
103
104 static void sizeTests(Deque<Integer> deque) throws Exception {
105 if (deque.size() != size())
106 throw new Exception("Size: " + deque.size() +
107 ", expecting " + size());
108 if (deque.isEmpty() != (size() == 0))
109 throw new Exception(
110 "IsEmpty " + deque.isEmpty() + ", size " + size());
111 // Check head and tail
112 if (size() == 0)
113 testEmpty(deque);
114 else
115 nonEmptyTest(deque);
116
117 }
118
119 static void nonEmptyTest(Deque<Integer> deque) throws Exception {
120 if (deque.getFirst() != nextHead + 1)
121 throw new Exception("getFirst got: " +
122 deque.getFirst() + " expecting " + (nextHead + 1));
123 if (deque.element() != nextHead + 1)
124 throw new Exception("element got: " + deque.element() +
125 " expecting " + (nextHead + 1));
126 if (deque.peekFirst() != nextHead + 1)
127 throw new Exception("peekFirst got: "+deque.peekFirst() +
128 " expecting " + (nextHead + 1));
129 if (deque.peek() != nextHead + 1)
130 throw new Exception("peek got: " + deque.peek() +
131 " expecting " + (nextHead + 1));
132
133 if (deque.peekLast() != nextTail - 1)
134 throw new Exception("peekLast got: " + deque.peekLast() +
135 " expecting " + (nextTail - 1));
136 if (deque.getLast() != nextTail - 1)
137 throw new Exception("getLast got: " +
138 deque.getLast() + " expecting " + (nextTail - 1));
139 }
140
141
142 static void randomOp(Deque<Integer> deque) throws Exception {
143
144 // Perform a random operation
145 switch(random() & 3) {
146 case 0:
147 switch(random() & 3) {
148 case 0: deque.addLast(nextTail++); break;
149 case 1: deque.offerLast(nextTail++); break;
150 case 2: deque.offer(nextTail++); break;
151 case 3: deque.add(nextTail++); break;
152 default: throw new Exception("How'd we get here");
153 }
154 break;
155 case 1:
156 if (size() == 0) {
157 int result = 666;
158 boolean threw = false;
159 try {
160 switch(random(3)) {
161 case 0: result = deque.removeFirst(); break;
162 case 1: result = deque.remove(); break;
163 case 2: result = deque.pop(); break;
164 default: throw new Exception("How'd we get here");
165 }
166 } catch(NoSuchElementException e) {
167 threw = true;
168 }
169 if (!threw)
170 throw new Exception("Remove-no exception: " + result);
171 } else { // deque nonempty
172 int result = -1;
173 switch(random(5)) {
174 case 0: result = deque.removeFirst(); break;
175 case 1: result = deque.remove(); break;
176 case 2: result = deque.pop(); break;
177 case 3: result = deque.pollFirst(); break;
178 case 4: result = deque.poll(); break;
179 default: throw new Exception("How'd we get here");
180 }
181 if (result != ++nextHead)
182 throw new Exception(
183 "Removed "+ result + " expecting "+(nextHead - 1));
184 }
185 break;
186 case 2:
187 switch(random(3)) {
188 case 0: deque.addFirst(nextHead--); break;
189 case 1: deque.offerFirst(nextHead--); break;
190 case 2: deque.push(nextHead--); break;
191 default: throw new Exception("How'd we get here");
192 }
193 break;
194 case 3:
195 if (size() == 0) {
196 int result = -1;
197 boolean threw = false;
198 try {
199 result = deque.removeLast();
200 } catch(NoSuchElementException e) {
201 threw = true;
202 }
203 if (!threw)
204 throw new Exception("Remove-no exception: " + result);
205 } else { // deque nonempty
206 int result = ((random() & 1) == 0?
207 deque.removeLast() : deque.pollLast());
208 if (result != --nextTail)
209 throw new Exception(
210 "Removed "+ result + " expecting "+(nextTail + 1));
211 }
212 break;
213 default:
214 throw new Exception("How'd we get here");
215 }
216 }
217
218
219 private static void testEqual(Deque<Integer> d1, Deque<Integer> d2)
220 throws Exception
221 {
222 if (d1.size() != d2.size())
223 throw new Exception("Size " + d1.size() + " != " + d2.size());
224 Iterator<Integer> it = d2.iterator();
225 for(int i : d1) {
226 int j = it.next();
227 if (j != i)
228 throw new Exception("Element " + j + " != " + i);
229 }
230
231 for(int i : d1)
232 if (!d2.contains(i))
233 throw new Exception("d2 doesn't contain " + i);
234 for(int i : d2)
235 if (!d1.contains(i))
236 throw new Exception("d2 doesn't contain " + i);
237
238 if (d1.contains(Integer.MIN_VALUE))
239 throw new Exception("d2 contains Integer.MIN_VALUE");
240 if (d2.contains(Integer.MIN_VALUE))
241 throw new Exception("d2 contains Integer.MIN_VALUE");
242 if (d1.contains(null))
243 throw new Exception("d1 contains null");
244 if (d2.contains(null))
245 throw new Exception("d2 contains null");
246
247 if (!d1.containsAll(d2))
248 throw new Exception("d1 doesn't contain all of d2");
249 if (!d2.containsAll(d1))
250 throw new Exception("d2 doesn't contain all of d1");
251 Collection<Integer> c = Collections.singleton(Integer.MIN_VALUE);
252 if (d1.containsAll(c))
253 throw new Exception("d1 contains all of {Integer.MIN_VALUE }");
254 if (d2.containsAll(c))
255 throw new Exception("d2 contains all of {Integer.MIN_VALUE }");
256 }
257
258 private static <T> T deepCopy(T o) {
259 try {
260 ByteArrayOutputStream bos = new ByteArrayOutputStream();
261 ObjectOutputStream oos = new ObjectOutputStream(bos);
262 oos.writeObject(o);
263 oos.flush();
264 ByteArrayInputStream bin = new ByteArrayInputStream(
265 bos.toByteArray());
266 ObjectInputStream ois = new ObjectInputStream(bin);
267 return (T) ois.readObject();
268 } catch(Exception e) {
269 throw new IllegalArgumentException(e);
270 }
271 }
272
273 private static void testRemove(Deque<Integer> deque) throws Exception {
274 Deque<Integer> copy = null;
275 switch(random() & 1) {
276 case 0:
277 copy = (Deque<Integer>) deque.getClass().
278 getConstructor(Collection.class).newInstance(deque);
279 break;
280 case 1:
281 copy = deepCopy(deque);
282 break;
283 default:
284 throw new Exception("How'd we get here");
285 }
286
287 int numRemoved = 0;
288 for (Iterator<Integer> it = copy.iterator(); it.hasNext(); ) {
289 if ((it.next() & 1) == 0) {
290 it.remove();
291 numRemoved++;
292 }
293 }
294
295 if (copy.size() + numRemoved != size())
296 throw new Exception((copy.size() + numRemoved) + " != " + size());
297 for (int i : copy)
298 if ((i & 1) == 0)
299 throw new Exception("Even number still present: " + i);
300
301 List<Integer> elements = Arrays.asList(copy.toArray(new Integer[0]));
302 Collections.shuffle(elements);
303 for (int e : elements) {
304 if (!copy.contains(e))
305 throw new Exception(e + " missing.");
306
307 boolean removed = false;
308 switch(random(3)) {
309 case 0: removed = copy.remove(e); break;
310 case 1: removed = copy.removeFirstOccurrence(e); break;
311 case 2: removed = copy.removeLastOccurrence(e); break;
312 default: throw new Exception("How'd we get here");
313 }
314 if (!removed)
315 throw new Exception(e + " not removed.");
316
317 if (copy.contains(e))
318 throw new Exception(e + " present after removal.");
319 }
320
321 testEmpty(copy);
322
323 copy = (Deque<Integer>) deque.getClass().
324 getConstructor(Collection.class).newInstance(deque);
325 copy.retainAll(deque);
326 testEqual(deque, copy);
327 copy.removeAll(deque);
328 testEmpty(copy);
329 }
330
331 static boolean checkedThrows;
332
333 private static void testEmpty(Deque<Integer> deque) throws Exception {
334 if (!deque.isEmpty())
335 throw new Exception("Deque isn't empty");
336 if (deque.size() != 0)
337 throw new Exception("Deque size isn't zero");
338 if (!(deque.pollFirst() == null))
339 throw new Exception("pollFirst lies");
340 if (!(deque.poll() == null))
341 throw new Exception("poll lies");
342 if (!(deque.peekFirst() == null))
343 throw new Exception("peekFirst lies");
344 if (!(deque.peek() == null))
345 throw new Exception("peek lies");
346 if (!(deque.pollLast() == null))
347 throw new Exception("pollLast lies");
348 if (!(deque.peekLast() == null))
349 throw new Exception("peekLast lies");
350
351 if (!checkedThrows) {
352 checkedThrows = true;
353 boolean threw = false;
354 int result = 666;
355 try {
356 result = ((random() & 1) == 0?
357 deque.getFirst() : deque.element());
358 } catch(NoSuchElementException e) {
359 threw = true;
360 }
361 if (!threw)
362 throw new Exception("getFirst-no exception: "+result);
363 threw = false;
364 try {
365 result = deque.getLast();
366 } catch(NoSuchElementException e) {
367 threw = true;
368 }
369 if (!threw)
370 throw new Exception("getLast-no exception: "+result);
371 }
372
373 }
374 }