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

# Content
1 /*
2 * Written by Josh Bloch of Google Inc. and released to the public domain,
3 * as explained at http://creativecommons.org/publicdomain/zero/1.0/.
4 */
5
6 import java.io.*;
7 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 static int random(int bound) {
26 int x = seed;
27 int t = (x % 127773) * 16807 - (x / 127773) * 2836;
28 seed = (t > 0) ? t : t + 0x7fffffff;
29 return (t & 0x7fffffff) % bound;
30 }
31
32 static int random() {
33 int x = seed;
34 int t = (x % 127773) * 16807 - (x / 127773) * 2836;
35 seed = (t > 0) ? t : t + 0x7fffffff;
36 return (t & 0x7fffffff);
37 }
38
39 public static void main(String[] args) throws Exception {
40 Class<?> cls = Class.forName(args[0]);
41 int n = 1000000;
42
43 for (int j = 0; j < 3; ++j) {
44 @SuppressWarnings("unchecked")
45 Deque<Integer> deque = (Deque<Integer>) cls.newInstance();
46 nextTail = 0;
47 nextHead = -1;
48 long start = System.nanoTime();
49 mainTest(deque, n);
50 long end = System.nanoTime();
51 long elapsedTimeMillis = (end - start) / (1000L * 1000L);
52 System.out.printf("Time: %d ms%n", elapsedTimeMillis);
53 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 if ((i & 1023) == 0) {
68 testIter(deque);
69 testDescendingIter(deque);
70 }
71
72 // Test serialization and copying
73 if ((i & 4095) == 0) {
74 testEqual(deque, serialClone(deque));
75 testEqual(deque, copyConstructorClone(deque));
76 }
77
78 // Test fancy removal stuff once in a blue moon
79 if ((i & 8191) == 0)
80 testRemove(deque);
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 testDescendingIter(Deque<Integer> deque) throws Exception {
105 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 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 if (size() == 0)
126 testEmpty(deque);
127 else
128 nonEmptyTest(deque);
129
130 }
131
132 static void nonEmptyTest(Deque<Integer> deque) throws Exception {
133 if (deque.getFirst() != nextHead + 1)
134 throw new Exception("getFirst got: " +
135 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
146 if (deque.peekLast() != nextTail - 1)
147 throw new Exception("peekLast got: " + deque.peekLast() +
148 " expecting " + (nextTail - 1));
149 if (deque.getLast() != nextTail - 1)
150 throw new Exception("getLast got: " +
151 deque.getLast() + " expecting " + (nextTail - 1));
152 }
153
154 static void randomOp(Deque<Integer> deque) throws Exception {
155
156 // Perform a random operation
157 switch (random() & 3) {
158 case 0:
159 switch (random() & 3) {
160 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 switch (random(3)) {
173 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 } catch (NoSuchElementException e) {
179 threw = true;
180 }
181 if (!threw)
182 throw new Exception("Remove-no exception: " + result);
183 } else { // deque nonempty
184 int result = -1;
185 switch (random(5)) {
186 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 switch (random(3)) {
200 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 } catch (NoSuchElementException e) {
213 threw = true;
214 }
215 if (!threw)
216 throw new Exception("Remove-no exception: " + result);
217 } else { // deque nonempty
218 int result = ((random() & 1) == 0 ?
219 deque.removeLast() : deque.pollLast());
220 if (result != --nextTail)
221 throw new Exception(
222 "Removed "+ result + " expecting "+(nextTail + 1));
223 }
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 for (int i : d1) {
237 int j = it.next();
238 if (j != i)
239 throw new Exception("Element " + j + " != " + i);
240 }
241
242 for (int i : d1)
243 if (!d2.contains(i))
244 throw new Exception("d2 doesn't contain " + i);
245 for (int i : d2)
246 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 @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 return (T) ois.readObject();
285 }
286
287 private static void testRemove(Deque<Integer> deque) throws Exception {
288 Deque<Integer> copy = ((random() & 1) == 0) ?
289 copyConstructorClone(deque) :
290 serialClone(deque);
291
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 switch (random(3)) {
314 case 0: removed = copy.remove(e); break;
315 case 1: removed = copy.removeFirstOccurrence(e); break;
316 case 2: removed = copy.removeLastOccurrence(e); break;
317 default: throw new Exception("How'd we get here");
318 }
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 copy = copyConstructorClone(deque);
329 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 result = ((random() & 1) == 0 ?
361 deque.getFirst() : deque.element());
362 } catch (NoSuchElementException e) {
363 threw = true;
364 }
365 if (!threw)
366 throw new Exception("getFirst-no exception: "+result);
367 threw = false;
368 try {
369 result = deque.getLast();
370 } catch (NoSuchElementException e) {
371 threw = true;
372 }
373 if (!threw)
374 throw new Exception("getLast-no exception: "+result);
375 }
376
377 }
378 }