ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/DequeBash.java
Revision: 1.8
Committed: Thu Apr 14 23:16:10 2011 UTC (13 years, 1 month ago) by jsr166
Branch: MAIN
CVS Tags: release-1_7_0
Changes since 1.7: +1 -1 lines
Log Message:
whitespace

File Contents

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