ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/DequeBash.java
Revision: 1.12
Committed: Mon Aug 10 03:13:33 2015 UTC (8 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.11: +0 -2 lines
Log Message:
delete unwanted blank lines

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