ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentHashMapTest.java
Revision: 1.57
Committed: Sun Jan 7 22:59:18 2018 UTC (6 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.56: +7 -11 lines
Log Message:
use <>

File Contents

# Content
1 /*
2 * Written by Doug Lea and Martin Buchholz with assistance from
3 * members of JCP JSR-166 Expert Group and released to the public
4 * domain, as explained at
5 * http://creativecommons.org/publicdomain/zero/1.0/
6 * Other contributors include Andrew Wright, Jeffrey Hayes,
7 * Pat Fisher, Mike Judd.
8 */
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Enumeration;
15 import java.util.Iterator;
16 import java.util.Map;
17 import java.util.Random;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap;
20
21 import junit.framework.Test;
22
23 public class ConcurrentHashMapTest extends JSR166TestCase {
24 public static void main(String[] args) {
25 main(suite(), args);
26 }
27 public static Test suite() {
28 class Implementation implements MapImplementation {
29 public Class<?> klazz() { return ConcurrentHashMap.class; }
30 public Map emptyMap() { return new ConcurrentHashMap(); }
31 public Object makeKey(int i) { return i; }
32 public Object makeValue(int i) { return i; }
33 public boolean isConcurrent() { return true; }
34 public boolean permitsNullKeys() { return false; }
35 public boolean permitsNullValues() { return false; }
36 public boolean supportsSetValue() { return true; }
37 }
38 return newTestSuite(
39 ConcurrentHashMapTest.class,
40 MapTest.testSuite(new Implementation()));
41 }
42
43 /**
44 * Returns a new map from Integers 1-5 to Strings "A"-"E".
45 */
46 private static ConcurrentHashMap<Integer, String> map5() {
47 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
48 assertTrue(map.isEmpty());
49 map.put(one, "A");
50 map.put(two, "B");
51 map.put(three, "C");
52 map.put(four, "D");
53 map.put(five, "E");
54 assertFalse(map.isEmpty());
55 assertEquals(5, map.size());
56 return map;
57 }
58
59 /** Re-implement Integer.compare for old java versions */
60 static int compare(int x, int y) {
61 return (x < y) ? -1 : (x > y) ? 1 : 0;
62 }
63
64 // classes for testing Comparable fallbacks
65 static class BI implements Comparable<BI> {
66 private final int value;
67 BI(int value) { this.value = value; }
68 public int compareTo(BI other) {
69 return compare(value, other.value);
70 }
71 public boolean equals(Object x) {
72 return (x instanceof BI) && ((BI)x).value == value;
73 }
74 public int hashCode() { return 42; }
75 }
76 static class CI extends BI { CI(int value) { super(value); } }
77 static class DI extends BI { DI(int value) { super(value); } }
78
79 static class BS implements Comparable<BS> {
80 private final String value;
81 BS(String value) { this.value = value; }
82 public int compareTo(BS other) {
83 return value.compareTo(other.value);
84 }
85 public boolean equals(Object x) {
86 return (x instanceof BS) && value.equals(((BS)x).value);
87 }
88 public int hashCode() { return 42; }
89 }
90
91 static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
92 implements Comparable<LexicographicList<E>> {
93 LexicographicList(Collection<E> c) { super(c); }
94 LexicographicList(E e) { super(Collections.singleton(e)); }
95 public int compareTo(LexicographicList<E> other) {
96 int common = Math.min(size(), other.size());
97 int r = 0;
98 for (int i = 0; i < common; i++) {
99 if ((r = get(i).compareTo(other.get(i))) != 0)
100 break;
101 }
102 if (r == 0)
103 r = compare(size(), other.size());
104 return r;
105 }
106 private static final long serialVersionUID = 0;
107 }
108
109 static class CollidingObject {
110 final String value;
111 CollidingObject(final String value) { this.value = value; }
112 public int hashCode() { return this.value.hashCode() & 1; }
113 public boolean equals(final Object obj) {
114 return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value);
115 }
116 }
117
118 static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> {
119 ComparableCollidingObject(final String value) { super(value); }
120 public int compareTo(final ComparableCollidingObject o) {
121 return value.compareTo(o.value);
122 }
123 }
124
125 /**
126 * Inserted elements that are subclasses of the same Comparable
127 * class are found.
128 */
129 public void testComparableFamily() {
130 int size = 500; // makes measured test run time -> 60ms
131 ConcurrentHashMap<BI, Boolean> m = new ConcurrentHashMap<>();
132 for (int i = 0; i < size; i++) {
133 assertNull(m.put(new CI(i), true));
134 }
135 for (int i = 0; i < size; i++) {
136 assertTrue(m.containsKey(new CI(i)));
137 assertTrue(m.containsKey(new DI(i)));
138 }
139 }
140
141 /**
142 * Elements of classes with erased generic type parameters based
143 * on Comparable can be inserted and found.
144 */
145 public void testGenericComparable() {
146 int size = 120; // makes measured test run time -> 60ms
147 ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
148 for (int i = 0; i < size; i++) {
149 BI bi = new BI(i);
150 BS bs = new BS(String.valueOf(i));
151 LexicographicList<BI> bis = new LexicographicList<>(bi);
152 LexicographicList<BS> bss = new LexicographicList<>(bs);
153 assertNull(m.putIfAbsent(bis, true));
154 assertTrue(m.containsKey(bis));
155 if (m.putIfAbsent(bss, true) == null)
156 assertTrue(m.containsKey(bss));
157 assertTrue(m.containsKey(bis));
158 }
159 for (int i = 0; i < size; i++) {
160 assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
161 }
162 }
163
164 /**
165 * Elements of non-comparable classes equal to those of classes
166 * with erased generic type parameters based on Comparable can be
167 * inserted and found.
168 */
169 public void testGenericComparable2() {
170 int size = 500; // makes measured test run time -> 60ms
171 ConcurrentHashMap<Object, Boolean> m = new ConcurrentHashMap<>();
172 for (int i = 0; i < size; i++) {
173 m.put(Collections.singletonList(new BI(i)), true);
174 }
175
176 for (int i = 0; i < size; i++) {
177 LexicographicList<BI> bis = new LexicographicList<>(new BI(i));
178 assertTrue(m.containsKey(bis));
179 }
180 }
181
182 /**
183 * Mixtures of instances of comparable and non-comparable classes
184 * can be inserted and found.
185 */
186 public void testMixedComparable() {
187 int size = 1200; // makes measured test run time -> 35ms
188 ConcurrentHashMap<Object, Object> map = new ConcurrentHashMap<>();
189 Random rng = new Random();
190 for (int i = 0; i < size; i++) {
191 Object x;
192 switch (rng.nextInt(4)) {
193 case 0:
194 x = new Object();
195 break;
196 case 1:
197 x = new CollidingObject(Integer.toString(i));
198 break;
199 default:
200 x = new ComparableCollidingObject(Integer.toString(i));
201 }
202 assertNull(map.put(x, x));
203 }
204 int count = 0;
205 for (Object k : map.keySet()) {
206 assertEquals(map.get(k), k);
207 ++count;
208 }
209 assertEquals(count, size);
210 assertEquals(map.size(), size);
211 for (Object k : map.keySet()) {
212 assertEquals(map.put(k, k), k);
213 }
214 }
215
216 /**
217 * clear removes all pairs
218 */
219 public void testClear() {
220 ConcurrentHashMap map = map5();
221 map.clear();
222 assertEquals(0, map.size());
223 }
224
225 /**
226 * Maps with same contents are equal
227 */
228 public void testEquals() {
229 ConcurrentHashMap map1 = map5();
230 ConcurrentHashMap map2 = map5();
231 assertEquals(map1, map2);
232 assertEquals(map2, map1);
233 map1.clear();
234 assertFalse(map1.equals(map2));
235 assertFalse(map2.equals(map1));
236 }
237
238 /**
239 * hashCode() equals sum of each key.hashCode ^ value.hashCode
240 */
241 public void testHashCode() {
242 ConcurrentHashMap<Integer,String> map = map5();
243 int sum = 0;
244 for (Map.Entry<Integer,String> e : map.entrySet())
245 sum += e.getKey().hashCode() ^ e.getValue().hashCode();
246 assertEquals(sum, map.hashCode());
247 }
248
249 /**
250 * contains returns true for contained value
251 */
252 public void testContains() {
253 ConcurrentHashMap map = map5();
254 assertTrue(map.contains("A"));
255 assertFalse(map.contains("Z"));
256 }
257
258 /**
259 * containsKey returns true for contained key
260 */
261 public void testContainsKey() {
262 ConcurrentHashMap map = map5();
263 assertTrue(map.containsKey(one));
264 assertFalse(map.containsKey(zero));
265 }
266
267 /**
268 * containsValue returns true for held values
269 */
270 public void testContainsValue() {
271 ConcurrentHashMap map = map5();
272 assertTrue(map.containsValue("A"));
273 assertFalse(map.containsValue("Z"));
274 }
275
276 /**
277 * enumeration returns an enumeration containing the correct
278 * elements
279 */
280 public void testEnumeration() {
281 ConcurrentHashMap map = map5();
282 Enumeration e = map.elements();
283 int count = 0;
284 while (e.hasMoreElements()) {
285 count++;
286 e.nextElement();
287 }
288 assertEquals(5, count);
289 }
290
291 /**
292 * get returns the correct element at the given key,
293 * or null if not present
294 */
295 public void testGet() {
296 ConcurrentHashMap map = map5();
297 assertEquals("A", (String)map.get(one));
298 ConcurrentHashMap empty = new ConcurrentHashMap();
299 assertNull(map.get("anything"));
300 assertNull(empty.get("anything"));
301 }
302
303 /**
304 * isEmpty is true of empty map and false for non-empty
305 */
306 public void testIsEmpty() {
307 ConcurrentHashMap empty = new ConcurrentHashMap();
308 ConcurrentHashMap map = map5();
309 assertTrue(empty.isEmpty());
310 assertFalse(map.isEmpty());
311 }
312
313 /**
314 * keys returns an enumeration containing all the keys from the map
315 */
316 public void testKeys() {
317 ConcurrentHashMap map = map5();
318 Enumeration e = map.keys();
319 int count = 0;
320 while (e.hasMoreElements()) {
321 count++;
322 e.nextElement();
323 }
324 assertEquals(5, count);
325 }
326
327 /**
328 * keySet returns a Set containing all the keys
329 */
330 public void testKeySet() {
331 ConcurrentHashMap map = map5();
332 Set s = map.keySet();
333 assertEquals(5, s.size());
334 assertTrue(s.contains(one));
335 assertTrue(s.contains(two));
336 assertTrue(s.contains(three));
337 assertTrue(s.contains(four));
338 assertTrue(s.contains(five));
339 }
340
341 /**
342 * Test keySet().removeAll on empty map
343 */
344 public void testKeySet_empty_removeAll() {
345 ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
346 Set<Integer> set = map.keySet();
347 set.removeAll(Collections.emptyList());
348 assertTrue(map.isEmpty());
349 assertTrue(set.isEmpty());
350 // following is test for JDK-8163353
351 set.removeAll(Collections.emptySet());
352 assertTrue(map.isEmpty());
353 assertTrue(set.isEmpty());
354 }
355
356 /**
357 * keySet.toArray returns contains all keys
358 */
359 public void testKeySetToArray() {
360 ConcurrentHashMap map = map5();
361 Set s = map.keySet();
362 Object[] ar = s.toArray();
363 assertTrue(s.containsAll(Arrays.asList(ar)));
364 assertEquals(5, ar.length);
365 ar[0] = m10;
366 assertFalse(s.containsAll(Arrays.asList(ar)));
367 }
368
369 /**
370 * Values.toArray contains all values
371 */
372 public void testValuesToArray() {
373 ConcurrentHashMap map = map5();
374 Collection v = map.values();
375 Object[] ar = v.toArray();
376 ArrayList s = new ArrayList(Arrays.asList(ar));
377 assertEquals(5, ar.length);
378 assertTrue(s.contains("A"));
379 assertTrue(s.contains("B"));
380 assertTrue(s.contains("C"));
381 assertTrue(s.contains("D"));
382 assertTrue(s.contains("E"));
383 }
384
385 /**
386 * entrySet.toArray contains all entries
387 */
388 public void testEntrySetToArray() {
389 ConcurrentHashMap map = map5();
390 Set s = map.entrySet();
391 Object[] ar = s.toArray();
392 assertEquals(5, ar.length);
393 for (int i = 0; i < 5; ++i) {
394 assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
395 assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
396 }
397 }
398
399 /**
400 * values collection contains all values
401 */
402 public void testValues() {
403 ConcurrentHashMap map = map5();
404 Collection s = map.values();
405 assertEquals(5, s.size());
406 assertTrue(s.contains("A"));
407 assertTrue(s.contains("B"));
408 assertTrue(s.contains("C"));
409 assertTrue(s.contains("D"));
410 assertTrue(s.contains("E"));
411 }
412
413 /**
414 * entrySet contains all pairs
415 */
416 public void testEntrySet() {
417 ConcurrentHashMap map = map5();
418 Set s = map.entrySet();
419 assertEquals(5, s.size());
420 Iterator it = s.iterator();
421 while (it.hasNext()) {
422 Map.Entry e = (Map.Entry) it.next();
423 assertTrue(
424 (e.getKey().equals(one) && e.getValue().equals("A")) ||
425 (e.getKey().equals(two) && e.getValue().equals("B")) ||
426 (e.getKey().equals(three) && e.getValue().equals("C")) ||
427 (e.getKey().equals(four) && e.getValue().equals("D")) ||
428 (e.getKey().equals(five) && e.getValue().equals("E")));
429 }
430 }
431
432 /**
433 * putAll adds all key-value pairs from the given map
434 */
435 public void testPutAll() {
436 ConcurrentHashMap empty = new ConcurrentHashMap();
437 ConcurrentHashMap map = map5();
438 empty.putAll(map);
439 assertEquals(5, empty.size());
440 assertTrue(empty.containsKey(one));
441 assertTrue(empty.containsKey(two));
442 assertTrue(empty.containsKey(three));
443 assertTrue(empty.containsKey(four));
444 assertTrue(empty.containsKey(five));
445 }
446
447 /**
448 * putIfAbsent works when the given key is not present
449 */
450 public void testPutIfAbsent() {
451 ConcurrentHashMap map = map5();
452 map.putIfAbsent(six, "Z");
453 assertTrue(map.containsKey(six));
454 }
455
456 /**
457 * putIfAbsent does not add the pair if the key is already present
458 */
459 public void testPutIfAbsent2() {
460 ConcurrentHashMap map = map5();
461 assertEquals("A", map.putIfAbsent(one, "Z"));
462 }
463
464 /**
465 * replace fails when the given key is not present
466 */
467 public void testReplace() {
468 ConcurrentHashMap map = map5();
469 assertNull(map.replace(six, "Z"));
470 assertFalse(map.containsKey(six));
471 }
472
473 /**
474 * replace succeeds if the key is already present
475 */
476 public void testReplace2() {
477 ConcurrentHashMap map = map5();
478 assertNotNull(map.replace(one, "Z"));
479 assertEquals("Z", map.get(one));
480 }
481
482 /**
483 * replace value fails when the given key not mapped to expected value
484 */
485 public void testReplaceValue() {
486 ConcurrentHashMap map = map5();
487 assertEquals("A", map.get(one));
488 assertFalse(map.replace(one, "Z", "Z"));
489 assertEquals("A", map.get(one));
490 }
491
492 /**
493 * replace value succeeds when the given key mapped to expected value
494 */
495 public void testReplaceValue2() {
496 ConcurrentHashMap map = map5();
497 assertEquals("A", map.get(one));
498 assertTrue(map.replace(one, "A", "Z"));
499 assertEquals("Z", map.get(one));
500 }
501
502 /**
503 * remove removes the correct key-value pair from the map
504 */
505 public void testRemove() {
506 ConcurrentHashMap map = map5();
507 map.remove(five);
508 assertEquals(4, map.size());
509 assertFalse(map.containsKey(five));
510 }
511
512 /**
513 * remove(key,value) removes only if pair present
514 */
515 public void testRemove2() {
516 ConcurrentHashMap map = map5();
517 map.remove(five, "E");
518 assertEquals(4, map.size());
519 assertFalse(map.containsKey(five));
520 map.remove(four, "A");
521 assertEquals(4, map.size());
522 assertTrue(map.containsKey(four));
523 }
524
525 /**
526 * size returns the correct values
527 */
528 public void testSize() {
529 ConcurrentHashMap map = map5();
530 ConcurrentHashMap empty = new ConcurrentHashMap();
531 assertEquals(0, empty.size());
532 assertEquals(5, map.size());
533 }
534
535 /**
536 * toString contains toString of elements
537 */
538 public void testToString() {
539 ConcurrentHashMap map = map5();
540 String s = map.toString();
541 for (int i = 1; i <= 5; ++i) {
542 assertTrue(s.contains(String.valueOf(i)));
543 }
544 }
545
546 // Exception tests
547
548 /**
549 * Cannot create with only negative capacity
550 */
551 public void testConstructor1() {
552 try {
553 new ConcurrentHashMap(-1);
554 shouldThrow();
555 } catch (IllegalArgumentException success) {}
556 }
557
558 /**
559 * Constructor (initialCapacity, loadFactor) throws
560 * IllegalArgumentException if either argument is negative
561 */
562 public void testConstructor2() {
563 try {
564 new ConcurrentHashMap(-1, .75f);
565 shouldThrow();
566 } catch (IllegalArgumentException success) {}
567
568 try {
569 new ConcurrentHashMap(16, -1);
570 shouldThrow();
571 } catch (IllegalArgumentException success) {}
572 }
573
574 /**
575 * Constructor (initialCapacity, loadFactor, concurrencyLevel)
576 * throws IllegalArgumentException if any argument is negative
577 */
578 public void testConstructor3() {
579 try {
580 new ConcurrentHashMap(-1, .75f, 1);
581 shouldThrow();
582 } catch (IllegalArgumentException success) {}
583
584 try {
585 new ConcurrentHashMap(16, -1, 1);
586 shouldThrow();
587 } catch (IllegalArgumentException success) {}
588
589 try {
590 new ConcurrentHashMap(16, .75f, -1);
591 shouldThrow();
592 } catch (IllegalArgumentException success) {}
593 }
594
595 /**
596 * ConcurrentHashMap(map) throws NullPointerException if the given
597 * map is null
598 */
599 public void testConstructor4() {
600 try {
601 new ConcurrentHashMap(null);
602 shouldThrow();
603 } catch (NullPointerException success) {}
604 }
605
606 /**
607 * ConcurrentHashMap(map) creates a new map with the same mappings
608 * as the given map
609 */
610 public void testConstructor5() {
611 ConcurrentHashMap map1 = map5();
612 ConcurrentHashMap map2 = new ConcurrentHashMap(map5());
613 assertTrue(map2.equals(map1));
614 map2.put(one, "F");
615 assertFalse(map2.equals(map1));
616 }
617
618 /**
619 * get(null) throws NPE
620 */
621 public void testGet_NullPointerException() {
622 ConcurrentHashMap c = new ConcurrentHashMap(5);
623 try {
624 c.get(null);
625 shouldThrow();
626 } catch (NullPointerException success) {}
627 }
628
629 /**
630 * containsKey(null) throws NPE
631 */
632 public void testContainsKey_NullPointerException() {
633 ConcurrentHashMap c = new ConcurrentHashMap(5);
634 try {
635 c.containsKey(null);
636 shouldThrow();
637 } catch (NullPointerException success) {}
638 }
639
640 /**
641 * containsValue(null) throws NPE
642 */
643 public void testContainsValue_NullPointerException() {
644 ConcurrentHashMap c = new ConcurrentHashMap(5);
645 try {
646 c.containsValue(null);
647 shouldThrow();
648 } catch (NullPointerException success) {}
649 }
650
651 /**
652 * contains(null) throws NPE
653 */
654 public void testContains_NullPointerException() {
655 ConcurrentHashMap c = new ConcurrentHashMap(5);
656 try {
657 c.contains(null);
658 shouldThrow();
659 } catch (NullPointerException success) {}
660 }
661
662 /**
663 * put(null,x) throws NPE
664 */
665 public void testPut1_NullPointerException() {
666 ConcurrentHashMap c = new ConcurrentHashMap(5);
667 try {
668 c.put(null, "whatever");
669 shouldThrow();
670 } catch (NullPointerException success) {}
671 }
672
673 /**
674 * put(x, null) throws NPE
675 */
676 public void testPut2_NullPointerException() {
677 ConcurrentHashMap c = new ConcurrentHashMap(5);
678 try {
679 c.put("whatever", null);
680 shouldThrow();
681 } catch (NullPointerException success) {}
682 }
683
684 /**
685 * putIfAbsent(null, x) throws NPE
686 */
687 public void testPutIfAbsent1_NullPointerException() {
688 ConcurrentHashMap c = new ConcurrentHashMap(5);
689 try {
690 c.putIfAbsent(null, "whatever");
691 shouldThrow();
692 } catch (NullPointerException success) {}
693 }
694
695 /**
696 * replace(null, x) throws NPE
697 */
698 public void testReplace_NullPointerException() {
699 ConcurrentHashMap c = new ConcurrentHashMap(5);
700 try {
701 c.replace(null, "whatever");
702 shouldThrow();
703 } catch (NullPointerException success) {}
704 }
705
706 /**
707 * replace(null, x, y) throws NPE
708 */
709 public void testReplaceValue_NullPointerException() {
710 ConcurrentHashMap c = new ConcurrentHashMap(5);
711 try {
712 c.replace(null, one, "whatever");
713 shouldThrow();
714 } catch (NullPointerException success) {}
715 }
716
717 /**
718 * putIfAbsent(x, null) throws NPE
719 */
720 public void testPutIfAbsent2_NullPointerException() {
721 ConcurrentHashMap c = new ConcurrentHashMap(5);
722 try {
723 c.putIfAbsent("whatever", null);
724 shouldThrow();
725 } catch (NullPointerException success) {}
726 }
727
728 /**
729 * replace(x, null) throws NPE
730 */
731 public void testReplace2_NullPointerException() {
732 ConcurrentHashMap c = new ConcurrentHashMap(5);
733 try {
734 c.replace("whatever", null);
735 shouldThrow();
736 } catch (NullPointerException success) {}
737 }
738
739 /**
740 * replace(x, null, y) throws NPE
741 */
742 public void testReplaceValue2_NullPointerException() {
743 ConcurrentHashMap c = new ConcurrentHashMap(5);
744 try {
745 c.replace("whatever", null, "A");
746 shouldThrow();
747 } catch (NullPointerException success) {}
748 }
749
750 /**
751 * replace(x, y, null) throws NPE
752 */
753 public void testReplaceValue3_NullPointerException() {
754 ConcurrentHashMap c = new ConcurrentHashMap(5);
755 try {
756 c.replace("whatever", one, null);
757 shouldThrow();
758 } catch (NullPointerException success) {}
759 }
760
761 /**
762 * remove(null) throws NPE
763 */
764 public void testRemove1_NullPointerException() {
765 ConcurrentHashMap c = new ConcurrentHashMap(5);
766 c.put("sadsdf", "asdads");
767 try {
768 c.remove(null);
769 shouldThrow();
770 } catch (NullPointerException success) {}
771 }
772
773 /**
774 * remove(null, x) throws NPE
775 */
776 public void testRemove2_NullPointerException() {
777 ConcurrentHashMap c = new ConcurrentHashMap(5);
778 c.put("sadsdf", "asdads");
779 try {
780 c.remove(null, "whatever");
781 shouldThrow();
782 } catch (NullPointerException success) {}
783 }
784
785 /**
786 * remove(x, null) returns false
787 */
788 public void testRemove3() {
789 ConcurrentHashMap c = new ConcurrentHashMap(5);
790 c.put("sadsdf", "asdads");
791 assertFalse(c.remove("sadsdf", null));
792 }
793
794 /**
795 * A deserialized/reserialized map equals original
796 */
797 public void testSerialization() throws Exception {
798 Map x = map5();
799 Map y = serialClone(x);
800
801 assertNotSame(x, y);
802 assertEquals(x.size(), y.size());
803 assertEquals(x, y);
804 assertEquals(y, x);
805 }
806
807 /**
808 * SetValue of an EntrySet entry sets value in the map.
809 */
810 public void testSetValueWriteThrough() {
811 // Adapted from a bug report by Eric Zoerner
812 ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
813 assertTrue(map.isEmpty());
814 for (int i = 0; i < 20; i++)
815 map.put(new Integer(i), new Integer(i));
816 assertFalse(map.isEmpty());
817 Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
818 // Unless it happens to be first (in which case remainder of
819 // test is skipped), remove a possibly-colliding key from map
820 // which, under some implementations, may cause entry1 to be
821 // cloned in map
822 if (!entry1.getKey().equals(new Integer(16))) {
823 map.remove(new Integer(16));
824 entry1.setValue("XYZ");
825 assertTrue(map.containsValue("XYZ")); // fails if write-through broken
826 }
827 }
828
829 /**
830 * Tests performance of removeAll when the other collection is much smaller.
831 * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testRemoveAll_performance -Djsr166.expensiveTests=true tck
832 */
833 public void testRemoveAll_performance() {
834 final int mapSize = expensiveTests ? 1_000_000 : 100;
835 final int iterations = expensiveTests ? 500 : 2;
836 final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
837 for (int i = 0; i < mapSize; i++)
838 map.put(i, i);
839 Set<Integer> keySet = map.keySet();
840 Collection<Integer> removeMe = Arrays.asList(new Integer[] { -99, -86 });
841 for (int i = 0; i < iterations; i++)
842 assertFalse(keySet.removeAll(removeMe));
843 assertEquals(mapSize, map.size());
844 }
845
846 }