1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 /*
17 * Written by Doug Lea with assistance from members of JCP JSR-166
18 * Expert Group and released to the public domain, as explained at
19 * http://creativecommons.org/licenses/publicdomain
20 */
21 package org.jboss.netty.util.internal;
22
23 import java.util.AbstractCollection;
24 import java.util.AbstractMap;
25 import java.util.AbstractSet;
26 import java.util.Arrays;
27 import java.util.Collection;
28 import java.util.ConcurrentModificationException;
29 import java.util.Enumeration;
30 import java.util.Hashtable;
31 import java.util.Iterator;
32 import java.util.Map;
33 import java.util.NoSuchElementException;
34 import java.util.Set;
35 import java.util.concurrent.ConcurrentMap;
36 import java.util.concurrent.locks.ReentrantLock;
37
38
39 /**
40 * An alternative identity-comparing {@link ConcurrentMap} which is similar to
41 * {@link java.util.concurrent.ConcurrentHashMap}.
42 * @param <K> the type of keys maintained by this map
43 * @param <V> the type of mapped values
44 */
45 public final class ConcurrentIdentityHashMap<K, V> extends AbstractMap<K, V>
46 implements ConcurrentMap<K, V> {
47
48 /**
49 * The default initial capacity for this table, used when not otherwise
50 * specified in a constructor.
51 */
52 static final int DEFAULT_INITIAL_CAPACITY = 16;
53
54 /**
55 * The default load factor for this table, used when not otherwise specified
56 * in a constructor.
57 */
58 static final float DEFAULT_LOAD_FACTOR = 0.75f;
59
60 /**
61 * The default concurrency level for this table, used when not otherwise
62 * specified in a constructor.
63 */
64 static final int DEFAULT_CONCURRENCY_LEVEL = 16;
65
66 /**
67 * The maximum capacity, used if a higher value is implicitly specified by
68 * either of the constructors with arguments. MUST be a power of two
69 * <= 1<<30 to ensure that entries are indexable using integers.
70 */
71 static final int MAXIMUM_CAPACITY = 1 << 30;
72
73 /**
74 * The maximum number of segments to allow; used to bound constructor
75 * arguments.
76 */
77 static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
78
79 /**
80 * Number of unsynchronized retries in size and containsValue methods before
81 * resorting to locking. This is used to avoid unbounded retries if tables
82 * undergo continuous modification which would make it impossible to obtain
83 * an accurate result.
84 */
85 static final int RETRIES_BEFORE_LOCK = 2;
86
87 /* ---------------- Fields -------------- */
88
89 /**
90 * Mask value for indexing into segments. The upper bits of a key's hash
91 * code are used to choose the segment.
92 */
93 final int segmentMask;
94
95 /**
96 * Shift value for indexing within segments.
97 */
98 final int segmentShift;
99
100 /**
101 * The segments, each of which is a specialized hash table
102 */
103 final Segment<K, V>[] segments;
104
105 Set<K> keySet;
106 Set<Map.Entry<K, V>> entrySet;
107 Collection<V> values;
108
109 /* ---------------- Small Utilities -------------- */
110
111 /**
112 * Applies a supplemental hash function to a given hashCode, which defends
113 * against poor quality hash functions. This is critical because
114 * ConcurrentReferenceHashMap uses power-of-two length hash tables, that
115 * otherwise encounter collisions for hashCodes that do not differ in lower
116 * or upper bits.
117 */
118 private static int hash(int h) {
119 // Spread bits to regularize both segment and index locations,
120 // using variant of single-word Wang/Jenkins hash.
121 h += h << 15 ^ 0xffffcd7d;
122 h ^= h >>> 10;
123 h += h << 3;
124 h ^= h >>> 6;
125 h += (h << 2) + (h << 14);
126 return h ^ h >>> 16;
127 }
128
129 /**
130 * Returns the segment that should be used for key with given hash.
131 *
132 * @param hash the hash code for the key
133 * @return the segment
134 */
135 Segment<K, V> segmentFor(int hash) {
136 return segments[hash >>> segmentShift & segmentMask];
137 }
138
139 private static int hashOf(Object key) {
140 return hash(System.identityHashCode(key));
141 }
142
143 /**
144 * ConcurrentReferenceHashMap list entry. Note that this is never exported
145 * out as a user-visible Map.Entry.
146 *
147 * Because the value field is volatile, not final, it is legal wrt
148 * the Java Memory Model for an unsynchronized reader to see null
149 * instead of initial value when read via a data race. Although a
150 * reordering leading to this is not likely to ever actually
151 * occur, the Segment.readValueUnderLock method is used as a
152 * backup in case a null (pre-initialized) value is ever seen in
153 * an unsynchronized access method.
154 */
155 static final class HashEntry<K, V> {
156 final Object key;
157 final int hash;
158 volatile Object value;
159 final HashEntry<K, V> next;
160
161 HashEntry(
162 K key, int hash, HashEntry<K, V> next, V value) {
163 this.hash = hash;
164 this.next = next;
165 this.key = key;
166 this.value = value;
167 }
168
169 @SuppressWarnings("unchecked")
170 K key() {
171 return (K) key;
172 }
173
174 @SuppressWarnings("unchecked")
175 V value() {
176 return (V) value;
177 }
178
179 void setValue(V value) {
180 this.value = value;
181 }
182
183 @SuppressWarnings("unchecked")
184 static <K, V> HashEntry<K, V>[] newArray(int i) {
185 return new HashEntry[i];
186 }
187 }
188
189 /**
190 * Segments are specialized versions of hash tables. This subclasses from
191 * ReentrantLock opportunistically, just to simplify some locking and avoid
192 * separate construction.
193 */
194 static final class Segment<K, V> extends ReentrantLock {
195 /*
196 * Segments maintain a table of entry lists that are ALWAYS kept in a
197 * consistent state, so can be read without locking. Next fields of
198 * nodes are immutable (final). All list additions are performed at the
199 * front of each bin. This makes it easy to check changes, and also fast
200 * to traverse. When nodes would otherwise be changed, new nodes are
201 * created to replace them. This works well for hash tables since the
202 * bin lists tend to be short. (The average length is less than two for
203 * the default load factor threshold.)
204 *
205 * Read operations can thus proceed without locking, but rely on
206 * selected uses of volatiles to ensure that completed write operations
207 * performed by other threads are noticed. For most purposes, the
208 * "count" field, tracking the number of elements, serves as that
209 * volatile variable ensuring visibility. This is convenient because
210 * this field needs to be read in many read operations anyway:
211 *
212 * - All (unsynchronized) read operations must first read the
213 * "count" field, and should not look at table entries if
214 * it is 0.
215 *
216 * - All (synchronized) write operations should write to
217 * the "count" field after structurally changing any bin.
218 * The operations must not take any action that could even
219 * momentarily cause a concurrent read operation to see
220 * inconsistent data. This is made easier by the nature of
221 * the read operations in Map. For example, no operation
222 * can reveal that the table has grown but the threshold
223 * has not yet been updated, so there are no atomicity
224 * requirements for this with respect to reads.
225 *
226 * As a guide, all critical volatile reads and writes to the count field
227 * are marked in code comments.
228 */
229
230 private static final long serialVersionUID = 5207829234977119743L;
231
232 /**
233 * The number of elements in this segment's region.
234 */
235 transient volatile int count;
236
237 /**
238 * Number of updates that alter the size of the table. This is used
239 * during bulk-read methods to make sure they see a consistent snapshot:
240 * If modCounts change during a traversal of segments computing size or
241 * checking containsValue, then we might have an inconsistent view of
242 * state so (usually) must retry.
243 */
244 int modCount;
245
246 /**
247 * The table is rehashed when its size exceeds this threshold.
248 * (The value of this field is always <tt>(capacity * loadFactor)</tt>.)
249 */
250 int threshold;
251
252 /**
253 * The per-segment table.
254 */
255 transient volatile HashEntry<K, V>[] table;
256
257 /**
258 * The load factor for the hash table. Even though this value is same
259 * for all segments, it is replicated to avoid needing links to outer
260 * object.
261 */
262 final float loadFactor;
263
264 Segment(int initialCapacity, float lf) {
265 loadFactor = lf;
266 setTable(HashEntry.<K, V>newArray(initialCapacity));
267 }
268
269 @SuppressWarnings("unchecked")
270 static <K, V> Segment<K, V>[] newArray(int i) {
271 return new Segment[i];
272 }
273
274 private static boolean keyEq(Object src, Object dest) {
275 return src == dest;
276 }
277
278 /**
279 * Sets table to new HashEntry array. Call only while holding lock or in
280 * constructor.
281 */
282 void setTable(HashEntry<K, V>[] newTable) {
283 threshold = (int) (newTable.length * loadFactor);
284 table = newTable;
285 }
286
287 /**
288 * Returns properly casted first entry of bin for given hash.
289 */
290 HashEntry<K, V> getFirst(int hash) {
291 HashEntry<K, V>[] tab = table;
292 return tab[hash & tab.length - 1];
293 }
294
295 HashEntry<K, V> newHashEntry(
296 K key, int hash, HashEntry<K, V> next, V value) {
297 return new HashEntry<K, V>(key, hash, next, value);
298 }
299
300 /**
301 * Reads value field of an entry under lock. Called if value field ever
302 * appears to be null. This is possible only if a compiler happens to
303 * reorder a HashEntry initialization with its table assignment, which
304 * is legal under memory model but is not known to ever occur.
305 */
306 V readValueUnderLock(HashEntry<K, V> e) {
307 lock();
308 try {
309 return e.value();
310 } finally {
311 unlock();
312 }
313 }
314
315 /* Specialized implementations of map methods */
316
317 V get(Object key, int hash) {
318 if (count != 0) { // read-volatile
319 HashEntry<K, V>[] tab = table;
320 HashEntry<K, V> e = tab[hash & tab.length - 1];
321 if (tab != table) {
322 return get(key, hash);
323 }
324 while (e != null) {
325 if (e.hash == hash && keyEq(key, e.key())) {
326 V opaque = e.value();
327 if (opaque != null) {
328 return opaque;
329 }
330
331 return readValueUnderLock(e); // recheck
332 }
333 e = e.next;
334 }
335 }
336 return null;
337 }
338
339 boolean containsKey(Object key, int hash) {
340 if (count != 0) { // read-volatile
341 HashEntry<K, V>[] tab = table;
342 HashEntry<K, V> e = tab[hash & tab.length - 1];
343 if (tab != table) {
344 return containsKey(key, hash);
345 }
346 while (e != null) {
347 if (e.hash == hash && keyEq(key, e.key())) {
348 return true;
349 }
350 e = e.next;
351 }
352 }
353 return false;
354 }
355
356 boolean containsValue(Object value) {
357 if (count != 0) { // read-volatile
358 HashEntry<K, V>[] tab = table;
359 for (HashEntry<K, V> e: tab) {
360 for (; e != null; e = e.next) {
361 V opaque = e.value();
362 V v;
363
364 if (opaque == null) {
365 v = readValueUnderLock(e); // recheck
366 } else {
367 v = opaque;
368 }
369
370 if (value.equals(v)) {
371 return true;
372 }
373 }
374 }
375 if (table != tab) {
376 return containsValue(value);
377 }
378 }
379 return false;
380 }
381
382 boolean replace(K key, int hash, V oldValue, V newValue) {
383 lock();
384 try {
385 HashEntry<K, V> e = getFirst(hash);
386 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
387 e = e.next;
388 }
389
390 boolean replaced = false;
391 if (e != null && oldValue.equals(e.value())) {
392 replaced = true;
393 e.setValue(newValue);
394 }
395 return replaced;
396 } finally {
397 unlock();
398 }
399 }
400
401 V replace(K key, int hash, V newValue) {
402 lock();
403 try {
404 HashEntry<K, V> e = getFirst(hash);
405 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
406 e = e.next;
407 }
408
409 V oldValue = null;
410 if (e != null) {
411 oldValue = e.value();
412 e.setValue(newValue);
413 }
414 return oldValue;
415 } finally {
416 unlock();
417 }
418 }
419
420 V put(K key, int hash, V value, boolean onlyIfAbsent) {
421 lock();
422 try {
423 int c = count;
424 if (c ++ > threshold) { // ensure capacity
425 int reduced = rehash();
426 if (reduced > 0) {
427 count = (c -= reduced) - 1; // write-volatile
428 }
429 }
430
431 HashEntry<K, V>[] tab = table;
432 int index = hash & tab.length - 1;
433 HashEntry<K, V> first = tab[index];
434 HashEntry<K, V> e = first;
435 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
436 e = e.next;
437 }
438
439 V oldValue;
440 if (e != null) {
441 oldValue = e.value();
442 if (!onlyIfAbsent) {
443 e.setValue(value);
444 }
445 } else {
446 oldValue = null;
447 ++ modCount;
448 tab[index] = newHashEntry(key, hash, first, value);
449 count = c; // write-volatile
450 }
451 return oldValue;
452 } finally {
453 unlock();
454 }
455 }
456
457 int rehash() {
458 HashEntry<K, V>[] oldTable = table;
459 int oldCapacity = oldTable.length;
460 if (oldCapacity >= MAXIMUM_CAPACITY) {
461 return 0;
462 }
463
464 /*
465 * Reclassify nodes in each list to new Map. Because we are using
466 * power-of-two expansion, the elements from each bin must either
467 * stay at same index, or move with a power of two offset. We
468 * eliminate unnecessary node creation by catching cases where old
469 * nodes can be reused because their next fields won't change.
470 * Statistically, at the default threshold, only about one-sixth of
471 * them need cloning when a table doubles. The nodes they replace
472 * will be garbage collectable as soon as they are no longer
473 * referenced by any reader thread that may be in the midst of
474 * traversing table right now.
475 */
476
477 HashEntry<K, V>[] newTable = HashEntry.newArray(oldCapacity << 1);
478 threshold = (int) (newTable.length * loadFactor);
479 int sizeMask = newTable.length - 1;
480 int reduce = 0;
481 for (HashEntry<K, V> e: oldTable) {
482 // We need to guarantee that any existing reads of old Map can
483 // proceed. So we cannot yet null out each bin.
484 if (e != null) {
485 HashEntry<K, V> next = e.next;
486 int idx = e.hash & sizeMask;
487
488 // Single node on list
489 if (next == null) {
490 newTable[idx] = e;
491 } else {
492 // Reuse trailing consecutive sequence at same slot
493 HashEntry<K, V> lastRun = e;
494 int lastIdx = idx;
495 for (HashEntry<K, V> last = next; last != null; last = last.next) {
496 int k = last.hash & sizeMask;
497 if (k != lastIdx) {
498 lastIdx = k;
499 lastRun = last;
500 }
501 }
502 newTable[lastIdx] = lastRun;
503 // Clone all remaining nodes
504 for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
505 // Skip GC'd weak references
506 K key = p.key();
507 if (key == null) {
508 reduce++;
509 continue;
510 }
511 int k = p.hash & sizeMask;
512 HashEntry<K, V> n = newTable[k];
513 newTable[k] = newHashEntry(key, p.hash, n, p.value());
514 }
515 }
516 }
517 }
518 table = newTable;
519 Arrays.fill(oldTable, null);
520 return reduce;
521 }
522
523 /**
524 * Remove; match on key only if value null, else match both.
525 */
526 V remove(Object key, int hash, Object value, boolean refRemove) {
527 lock();
528 try {
529 int c = count - 1;
530 HashEntry<K, V>[] tab = table;
531 int index = hash & tab.length - 1;
532 HashEntry<K, V> first = tab[index];
533 HashEntry<K, V> e = first;
534 // a reference remove operation compares the Reference instance
535 while (e != null && key != e.key &&
536 (refRemove || hash != e.hash || !keyEq(key, e.key()))) {
537 e = e.next;
538 }
539
540 V oldValue = null;
541 if (e != null) {
542 V v = e.value();
543 if (value == null || value.equals(v)) {
544 oldValue = v;
545 // All entries following removed node can stay in list,
546 // but all preceding ones need to be cloned.
547 ++ modCount;
548 HashEntry<K, V> newFirst = e.next;
549 for (HashEntry<K, V> p = first; p != e; p = p.next) {
550 K pKey = p.key();
551 if (pKey == null) { // Skip GC'd keys
552 c --;
553 continue;
554 }
555
556 newFirst = newHashEntry(
557 pKey, p.hash, newFirst, p.value());
558 }
559 tab[index] = newFirst;
560 count = c; // write-volatile
561 }
562 }
563 return oldValue;
564 } finally {
565 unlock();
566 }
567 }
568
569 void clear() {
570 if (count != 0) {
571 lock();
572 try {
573 HashEntry<K, V>[] tab = table;
574 for (int i = 0; i < tab.length; i ++) {
575 tab[i] = null;
576 }
577 ++ modCount;
578 count = 0; // write-volatile
579 } finally {
580 unlock();
581 }
582 }
583 }
584 }
585
586 /* ---------------- Public operations -------------- */
587
588 /**
589 * Creates a new, empty map with the specified initial capacity, load factor
590 * and concurrency level.
591 *
592 * @param initialCapacity the initial capacity. The implementation performs
593 * internal sizing to accommodate this many elements.
594 * @param loadFactor the load factor threshold, used to control resizing.
595 * Resizing may be performed when the average number of
596 * elements per bin exceeds this threshold.
597 * @param concurrencyLevel the estimated number of concurrently updating
598 * threads. The implementation performs internal
599 * sizing to try to accommodate this many threads.
600 * @throws IllegalArgumentException if the initial capacity is negative or
601 * the load factor or concurrencyLevel are
602 * nonpositive.
603 */
604 public ConcurrentIdentityHashMap(
605 int initialCapacity, float loadFactor,
606 int concurrencyLevel) {
607 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) {
608 throw new IllegalArgumentException();
609 }
610
611 if (concurrencyLevel > MAX_SEGMENTS) {
612 concurrencyLevel = MAX_SEGMENTS;
613 }
614
615 // Find power-of-two sizes best matching arguments
616 int sshift = 0;
617 int ssize = 1;
618 while (ssize < concurrencyLevel) {
619 ++ sshift;
620 ssize <<= 1;
621 }
622 segmentShift = 32 - sshift;
623 segmentMask = ssize - 1;
624 segments = Segment.newArray(ssize);
625
626 if (initialCapacity > MAXIMUM_CAPACITY) {
627 initialCapacity = MAXIMUM_CAPACITY;
628 }
629 int c = initialCapacity / ssize;
630 if (c * ssize < initialCapacity) {
631 ++ c;
632 }
633 int cap = 1;
634 while (cap < c) {
635 cap <<= 1;
636 }
637
638 for (int i = 0; i < segments.length; ++ i) {
639 segments[i] = new Segment<K, V>(cap, loadFactor);
640 }
641 }
642
643
644 /**
645 * Creates a new, empty map with the specified initial capacity and load
646 * factor and with the default reference types (weak keys, strong values),
647 * and concurrencyLevel (16).
648 *
649 * @param initialCapacity The implementation performs internal sizing to
650 * accommodate this many elements.
651 * @param loadFactor the load factor threshold, used to control resizing.
652 * Resizing may be performed when the average number of
653 * elements per bin exceeds this threshold.
654 * @throws IllegalArgumentException if the initial capacity of elements is
655 * negative or the load factor is
656 * nonpositive
657 */
658 public ConcurrentIdentityHashMap(int initialCapacity, float loadFactor) {
659 this(initialCapacity, loadFactor, DEFAULT_CONCURRENCY_LEVEL);
660 }
661
662 /**
663 * Creates a new, empty map with the specified initial capacity, and with
664 * default reference types (weak keys, strong values), load factor (0.75)
665 * and concurrencyLevel (16).
666 *
667 * @param initialCapacity the initial capacity. The implementation performs
668 * internal sizing to accommodate this many elements.
669 * @throws IllegalArgumentException if the initial capacity of elements is
670 * negative.
671 */
672 public ConcurrentIdentityHashMap(int initialCapacity) {
673 this(initialCapacity, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
674 }
675
676 /**
677 * Creates a new, empty map with a default initial capacity (16), reference
678 * types (weak keys, strong values), default load factor (0.75) and
679 * concurrencyLevel (16).
680 */
681 public ConcurrentIdentityHashMap() {
682 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, DEFAULT_CONCURRENCY_LEVEL);
683 }
684
685 /**
686 * Creates a new map with the same mappings as the given map. The map is
687 * created with a capacity of 1.5 times the number of mappings in the given
688 * map or 16 (whichever is greater), and a default load factor (0.75) and
689 * concurrencyLevel (16).
690 *
691 * @param m the map
692 */
693 public ConcurrentIdentityHashMap(Map<? extends K, ? extends V> m) {
694 this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
695 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR,
696 DEFAULT_CONCURRENCY_LEVEL);
697 putAll(m);
698 }
699
700 /**
701 * Returns <tt>true</tt> if this map contains no key-value mappings.
702 *
703 * @return <tt>true</tt> if this map contains no key-value mappings
704 */
705 @Override
706 public boolean isEmpty() {
707 final Segment<K, V>[] segments = this.segments;
708 /*
709 * We keep track of per-segment modCounts to avoid ABA problems in which
710 * an element in one segment was added and in another removed during
711 * traversal, in which case the table was never actually empty at any
712 * point. Note the similar use of modCounts in the size() and
713 * containsValue() methods, which are the only other methods also
714 * susceptible to ABA problems.
715 */
716 int[] mc = new int[segments.length];
717 int mcsum = 0;
718 for (int i = 0; i < segments.length; ++ i) {
719 if (segments[i].count != 0) {
720 return false;
721 } else {
722 mcsum += mc[i] = segments[i].modCount;
723 }
724 }
725 // If mcsum happens to be zero, then we know we got a snapshot before
726 // any modifications at all were made. This is probably common enough
727 // to bother tracking.
728 if (mcsum != 0) {
729 for (int i = 0; i < segments.length; ++ i) {
730 if (segments[i].count != 0 || mc[i] != segments[i].modCount) {
731 return false;
732 }
733 }
734 }
735 return true;
736 }
737
738 /**
739 * Returns the number of key-value mappings in this map. If the map contains
740 * more than <tt>Integer.MAX_VALUE</tt> elements, returns
741 * <tt>Integer.MAX_VALUE</tt>.
742 *
743 * @return the number of key-value mappings in this map
744 */
745 @Override
746 public int size() {
747 final Segment<K, V>[] segments = this.segments;
748 long sum = 0;
749 long check = 0;
750 int[] mc = new int[segments.length];
751 // Try a few times to get accurate count. On failure due to continuous
752 // async changes in table, resort to locking.
753 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++ k) {
754 check = 0;
755 sum = 0;
756 int mcsum = 0;
757 for (int i = 0; i < segments.length; ++ i) {
758 sum += segments[i].count;
759 mcsum += mc[i] = segments[i].modCount;
760 }
761 if (mcsum != 0) {
762 for (int i = 0; i < segments.length; ++ i) {
763 check += segments[i].count;
764 if (mc[i] != segments[i].modCount) {
765 check = -1; // force retry
766 break;
767 }
768 }
769 }
770 if (check == sum) {
771 break;
772 }
773 }
774 if (check != sum) { // Resort to locking all segments
775 sum = 0;
776 for (Segment<K, V> segment: segments) {
777 segment.lock();
778 }
779 for (Segment<K, V> segment: segments) {
780 sum += segment.count;
781 }
782 for (Segment<K, V> segment: segments) {
783 segment.unlock();
784 }
785 }
786 if (sum > Integer.MAX_VALUE) {
787 return Integer.MAX_VALUE;
788 } else {
789 return (int) sum;
790 }
791 }
792
793 /**
794 * Returns the value to which the specified key is mapped, or {@code null}
795 * if this map contains no mapping for the key.
796 *
797 * <p>More formally, if this map contains a mapping from a key {@code k} to
798 * a value {@code v} such that {@code key.equals(k)}, then this method
799 * returns {@code v}; otherwise it returns {@code null}. (There can be at
800 * most one such mapping.)
801 *
802 * @throws NullPointerException if the specified key is null
803 */
804 @Override
805 public V get(Object key) {
806 int hash = hashOf(key);
807 return segmentFor(hash).get(key, hash);
808 }
809
810 /**
811 * Tests if the specified object is a key in this table.
812 *
813 * @param key possible key
814 * @return <tt>true</tt> if and only if the specified object is a key in
815 * this table, as determined by the <tt>equals</tt> method;
816 * <tt>false</tt> otherwise.
817 * @throws NullPointerException if the specified key is null
818 */
819 @Override
820 public boolean containsKey(Object key) {
821 int hash = hashOf(key);
822 return segmentFor(hash).containsKey(key, hash);
823 }
824
825 /**
826 * Returns <tt>true</tt> if this map maps one or more keys to the specified
827 * value. Note: This method requires a full internal traversal of the hash
828 * table, and so is much slower than method <tt>containsKey</tt>.
829 *
830 * @param value value whose presence in this map is to be tested
831 * @return <tt>true</tt> if this map maps one or more keys to the specified
832 * value
833 * @throws NullPointerException if the specified value is null
834 */
835
836 @Override
837 public boolean containsValue(Object value) {
838 if (value == null) {
839 throw new NullPointerException();
840 }
841
842 // See explanation of modCount use above
843
844 final Segment<K, V>[] segments = this.segments;
845 int[] mc = new int[segments.length];
846
847 // Try a few times without locking
848 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++ k) {
849 int mcsum = 0;
850 for (int i = 0; i < segments.length; ++ i) {
851 mcsum += mc[i] = segments[i].modCount;
852 if (segments[i].containsValue(value)) {
853 return true;
854 }
855 }
856 boolean cleanSweep = true;
857 if (mcsum != 0) {
858 for (int i = 0; i < segments.length; ++ i) {
859 if (mc[i] != segments[i].modCount) {
860 cleanSweep = false;
861 break;
862 }
863 }
864 }
865 if (cleanSweep) {
866 return false;
867 }
868 }
869 // Resort to locking all segments
870 for (Segment<K, V> segment: segments) {
871 segment.lock();
872 }
873 boolean found = false;
874 try {
875 for (Segment<K, V> segment: segments) {
876 if (segment.containsValue(value)) {
877 found = true;
878 break;
879 }
880 }
881 } finally {
882 for (Segment<K, V> segment: segments) {
883 segment.unlock();
884 }
885 }
886 return found;
887 }
888
889 /**
890 * Legacy method testing if some key maps into the specified value in this
891 * table. This method is identical in functionality to
892 * {@link #containsValue}, and exists solely to ensure full compatibility
893 * with class {@link Hashtable}, which supported this method prior to
894 * introduction of the Java Collections framework.
895 *
896 * @param value a value to search for
897 * @return <tt>true</tt> if and only if some key maps to the <tt>value</tt>
898 * argument in this table as determined by the <tt>equals</tt>
899 * method; <tt>false</tt> otherwise
900 * @throws NullPointerException if the specified value is null
901 */
902 public boolean contains(Object value) {
903 return containsValue(value);
904 }
905
906 /**
907 * Maps the specified key to the specified value in this table. Neither the
908 * key nor the value can be null.
909 *
910 * <p>The value can be retrieved by calling the <tt>get</tt> method with a
911 * key that is equal to the original key.
912 *
913 * @param key key with which the specified value is to be associated
914 * @param value value to be associated with the specified key
915 * @return the previous value associated with <tt>key</tt>, or <tt>null</tt>
916 * if there was no mapping for <tt>key</tt>
917 * @throws NullPointerException if the specified key or value is null
918 */
919 @Override
920 public V put(K key, V value) {
921 if (value == null) {
922 throw new NullPointerException();
923 }
924 int hash = hashOf(key);
925 return segmentFor(hash).put(key, hash, value, false);
926 }
927
928 /**
929 * @return the previous value associated with the specified key, or
930 * <tt>null</tt> if there was no mapping for the key
931 * @throws NullPointerException if the specified key or value is null
932 */
933 public V putIfAbsent(K key, V value) {
934 if (value == null) {
935 throw new NullPointerException();
936 }
937 int hash = hashOf(key);
938 return segmentFor(hash).put(key, hash, value, true);
939 }
940
941 /**
942 * Copies all of the mappings from the specified map to this one. These
943 * mappings replace any mappings that this map had for any of the keys
944 * currently in the specified map.
945 *
946 * @param m mappings to be stored in this map
947 */
948 @Override
949 public void putAll(Map<? extends K, ? extends V> m) {
950 for (Map.Entry<? extends K, ? extends V> e: m.entrySet()) {
951 put(e.getKey(), e.getValue());
952 }
953 }
954
955 /**
956 * Removes the key (and its corresponding value) from this map. This method
957 * does nothing if the key is not in the map.
958 *
959 * @param key the key that needs to be removed
960 * @return the previous value associated with <tt>key</tt>, or <tt>null</tt>
961 * if there was no mapping for <tt>key</tt>
962 * @throws NullPointerException if the specified key is null
963 */
964 @Override
965 public V remove(Object key) {
966 int hash = hashOf(key);
967 return segmentFor(hash).remove(key, hash, null, false);
968 }
969
970 /**
971 * @throws NullPointerException if the specified key is null
972 */
973 public boolean remove(Object key, Object value) {
974 int hash = hashOf(key);
975 if (value == null) {
976 return false;
977 }
978 return segmentFor(hash).remove(key, hash, value, false) != null;
979 }
980
981 /**
982 * @throws NullPointerException if any of the arguments are null
983 */
984 public boolean replace(K key, V oldValue, V newValue) {
985 if (oldValue == null || newValue == null) {
986 throw new NullPointerException();
987 }
988 int hash = hashOf(key);
989 return segmentFor(hash).replace(key, hash, oldValue, newValue);
990 }
991
992 /**
993 * @return the previous value associated with the specified key, or
994 * <tt>null</tt> if there was no mapping for the key
995 * @throws NullPointerException if the specified key or value is null
996 */
997 public V replace(K key, V value) {
998 if (value == null) {
999 throw new NullPointerException();
1000 }
1001 int hash = hashOf(key);
1002 return segmentFor(hash).replace(key, hash, value);
1003 }
1004
1005 /**
1006 * Removes all of the mappings from this map.
1007 */
1008 @Override
1009 public void clear() {
1010 for (Segment<K, V> segment: segments) {
1011 segment.clear();
1012 }
1013 }
1014
1015 /**
1016 * Returns a {@link Set} view of the keys contained in this map. The set is
1017 * backed by the map, so changes to the map are reflected in the set, and
1018 * vice-versa. The set supports element removal, which removes the
1019 * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
1020 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
1021 * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
1022 * <tt>addAll</tt> operations.
1023 *
1024 * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator that
1025 * will never throw {@link ConcurrentModificationException}, and guarantees
1026 * to traverse elements as they existed upon construction of the iterator,
1027 * and may (but is not guaranteed to) reflect any modifications subsequent
1028 * to construction.
1029 */
1030 @Override
1031 public Set<K> keySet() {
1032 Set<K> ks = keySet;
1033 return ks != null? ks : (keySet = new KeySet());
1034 }
1035
1036 /**
1037 * Returns a {@link Collection} view of the values contained in this map.
1038 * The collection is backed by the map, so changes to the map are reflected
1039 * in the collection, and vice-versa. The collection supports element
1040 * removal, which removes the corresponding mapping from this map, via the
1041 * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1042 * <tt>retainAll</tt>, and <tt>clear</tt> operations. It does not support
1043 * the <tt>add</tt> or <tt>addAll</tt> operations.
1044 *
1045 * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator that
1046 * will never throw {@link ConcurrentModificationException}, and guarantees
1047 * to traverse elements as they existed upon construction of the iterator,
1048 * and may (but is not guaranteed to) reflect any modifications subsequent
1049 * to construction.
1050 */
1051 @Override
1052 public Collection<V> values() {
1053 Collection<V> vs = values;
1054 return vs != null? vs : (values = new Values());
1055 }
1056
1057 /**
1058 * Returns a {@link Set} view of the mappings contained in this map.
1059 * The set is backed by the map, so changes to the map are reflected in the
1060 * set, and vice-versa. The set supports element removal, which removes the
1061 * corresponding mapping from the map, via the <tt>Iterator.remove</tt>,
1062 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
1063 * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
1064 * <tt>addAll</tt> operations.
1065 *
1066 * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator that
1067 * will never throw {@link ConcurrentModificationException}, and guarantees
1068 * to traverse elements as they existed upon construction of the iterator,
1069 * and may (but is not guaranteed to) reflect any modifications subsequent
1070 * to construction.
1071 */
1072 @Override
1073 public Set<Map.Entry<K, V>> entrySet() {
1074 Set<Map.Entry<K, V>> es = entrySet;
1075 return es != null? es : (entrySet = new EntrySet());
1076 }
1077
1078 /**
1079 * Returns an enumeration of the keys in this table.
1080 *
1081 * @return an enumeration of the keys in this table
1082 * @see #keySet()
1083 */
1084 public Enumeration<K> keys() {
1085 return new KeyIterator();
1086 }
1087
1088 /**
1089 * Returns an enumeration of the values in this table.
1090 *
1091 * @return an enumeration of the values in this table
1092 * @see #values()
1093 */
1094 public Enumeration<V> elements() {
1095 return new ValueIterator();
1096 }
1097
1098 /* ---------------- Iterator Support -------------- */
1099
1100 abstract class HashIterator {
1101 int nextSegmentIndex;
1102 int nextTableIndex;
1103 HashEntry<K, V>[] currentTable;
1104 HashEntry<K, V> nextEntry;
1105 HashEntry<K, V> lastReturned;
1106 K currentKey; // Strong reference to weak key (prevents gc)
1107
1108 HashIterator() {
1109 nextSegmentIndex = segments.length - 1;
1110 nextTableIndex = -1;
1111 advance();
1112 }
1113
1114 public void rewind() {
1115 nextSegmentIndex = segments.length - 1;
1116 nextTableIndex = -1;
1117 currentTable = null;
1118 nextEntry = null;
1119 lastReturned = null;
1120 currentKey = null;
1121 advance();
1122 }
1123
1124 public boolean hasMoreElements() {
1125 return hasNext();
1126 }
1127
1128 final void advance() {
1129 if (nextEntry != null && (nextEntry = nextEntry.next) != null) {
1130 return;
1131 }
1132
1133 while (nextTableIndex >= 0) {
1134 if ((nextEntry = currentTable[nextTableIndex --]) != null) {
1135 return;
1136 }
1137 }
1138
1139 while (nextSegmentIndex >= 0) {
1140 Segment<K, V> seg = segments[nextSegmentIndex --];
1141 if (seg.count != 0) {
1142 currentTable = seg.table;
1143 for (int j = currentTable.length - 1; j >= 0; -- j) {
1144 if ((nextEntry = currentTable[j]) != null) {
1145 nextTableIndex = j - 1;
1146 return;
1147 }
1148 }
1149 }
1150 }
1151 }
1152
1153 public boolean hasNext() {
1154 while (nextEntry != null) {
1155 if (nextEntry.key() != null) {
1156 return true;
1157 }
1158 advance();
1159 }
1160
1161 return false;
1162 }
1163
1164 HashEntry<K, V> nextEntry() {
1165 do {
1166 if (nextEntry == null) {
1167 throw new NoSuchElementException();
1168 }
1169
1170 lastReturned = nextEntry;
1171 currentKey = lastReturned.key();
1172 advance();
1173 } while (currentKey == null); // Skip GC'd keys
1174
1175 return lastReturned;
1176 }
1177
1178 public void remove() {
1179 if (lastReturned == null) {
1180 throw new IllegalStateException();
1181 }
1182 ConcurrentIdentityHashMap.this.remove(currentKey);
1183 lastReturned = null;
1184 }
1185 }
1186
1187 final class KeyIterator
1188 extends HashIterator implements ReusableIterator<K>, Enumeration<K> {
1189
1190 public K next() {
1191 return nextEntry().key();
1192 }
1193
1194 public K nextElement() {
1195 return nextEntry().key();
1196 }
1197 }
1198
1199 final class ValueIterator
1200 extends HashIterator implements ReusableIterator<V>, Enumeration<V> {
1201
1202 public V next() {
1203 return nextEntry().value();
1204 }
1205
1206 public V nextElement() {
1207 return nextEntry().value();
1208 }
1209 }
1210
1211 /*
1212 * This class is needed for JDK5 compatibility.
1213 */
1214 static class SimpleEntry<K, V> implements Entry<K, V> {
1215
1216 private final K key;
1217
1218 private V value;
1219
1220 public SimpleEntry(K key, V value) {
1221 this.key = key;
1222 this.value = value;
1223
1224 }
1225
1226 public SimpleEntry(Entry<? extends K, ? extends V> entry) {
1227 key = entry.getKey();
1228 value = entry.getValue();
1229
1230 }
1231
1232 public K getKey() {
1233 return key;
1234 }
1235
1236 public V getValue() {
1237 return value;
1238 }
1239
1240 public V setValue(V value) {
1241 V oldValue = this.value;
1242 this.value = value;
1243 return oldValue;
1244 }
1245
1246 @Override
1247 public boolean equals(Object o) {
1248 if (!(o instanceof Map.Entry<?, ?>)) {
1249 return false;
1250 }
1251 @SuppressWarnings("rawtypes")
1252 Map.Entry e = (Map.Entry) o;
1253 return eq(key, e.getKey()) && eq(value, e.getValue());
1254 }
1255
1256 @Override
1257 public int hashCode() {
1258 return (key == null? 0 : key.hashCode()) ^ (value == null? 0 : value.hashCode());
1259 }
1260
1261 @Override
1262 public String toString() {
1263 return key + "=" + value;
1264 }
1265
1266 private static boolean eq(Object o1, Object o2) {
1267 return o1 == null? o2 == null : o1.equals(o2);
1268 }
1269 }
1270
1271 /**
1272 * Custom Entry class used by EntryIterator.next(), that relays setValue
1273 * changes to the underlying map.
1274 */
1275 final class WriteThroughEntry extends SimpleEntry<K, V> {
1276
1277 WriteThroughEntry(K k, V v) {
1278 super(k, v);
1279 }
1280
1281 /**
1282 * Set our entry's value and write through to the map. The value to
1283 * return is somewhat arbitrary here. Since a WriteThroughEntry does not
1284 * necessarily track asynchronous changes, the most recent "previous"
1285 * value could be different from what we return (or could even have been
1286 * removed in which case the put will re-establish). We do not and can
1287 * not guarantee more.
1288 */
1289 @Override
1290 public V setValue(V value) {
1291
1292 if (value == null) {
1293 throw new NullPointerException();
1294 }
1295 V v = super.setValue(value);
1296 put(getKey(), value);
1297 return v;
1298 }
1299
1300 }
1301
1302 final class EntryIterator extends HashIterator implements
1303 ReusableIterator<Entry<K, V>> {
1304 public Map.Entry<K, V> next() {
1305 HashEntry<K, V> e = nextEntry();
1306 return new WriteThroughEntry(e.key(), e.value());
1307 }
1308 }
1309
1310 final class KeySet extends AbstractSet<K> {
1311 @Override
1312 public Iterator<K> iterator() {
1313
1314 return new KeyIterator();
1315 }
1316
1317 @Override
1318 public int size() {
1319 return ConcurrentIdentityHashMap.this.size();
1320 }
1321
1322 @Override
1323 public boolean isEmpty() {
1324 return ConcurrentIdentityHashMap.this.isEmpty();
1325 }
1326
1327 @Override
1328 public boolean contains(Object o) {
1329 return containsKey(o);
1330 }
1331
1332 @Override
1333 public boolean remove(Object o) {
1334 return ConcurrentIdentityHashMap.this.remove(o) != null;
1335
1336 }
1337
1338 @Override
1339 public void clear() {
1340 ConcurrentIdentityHashMap.this.clear();
1341 }
1342 }
1343
1344 final class Values extends AbstractCollection<V> {
1345 @Override
1346 public Iterator<V> iterator() {
1347 return new ValueIterator();
1348 }
1349
1350 @Override
1351 public int size() {
1352 return ConcurrentIdentityHashMap.this.size();
1353 }
1354
1355 @Override
1356 public boolean isEmpty() {
1357 return ConcurrentIdentityHashMap.this.isEmpty();
1358 }
1359
1360 @Override
1361 public boolean contains(Object o) {
1362 return containsValue(o);
1363 }
1364
1365 @Override
1366 public void clear() {
1367 ConcurrentIdentityHashMap.this.clear();
1368 }
1369 }
1370
1371 final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
1372 @Override
1373 public Iterator<Map.Entry<K, V>> iterator() {
1374 return new EntryIterator();
1375 }
1376
1377 @Override
1378 public boolean contains(Object o) {
1379 if (!(o instanceof Map.Entry<?, ?>)) {
1380 return false;
1381 }
1382 Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1383 V v = get(e.getKey());
1384 return v != null && v.equals(e.getValue());
1385 }
1386
1387 @Override
1388 public boolean remove(Object o) {
1389 if (!(o instanceof Map.Entry<?, ?>)) {
1390 return false;
1391 }
1392 Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1393 return ConcurrentIdentityHashMap.this.remove(e.getKey(), e.getValue());
1394 }
1395
1396 @Override
1397 public int size() {
1398 return ConcurrentIdentityHashMap.this.size();
1399 }
1400
1401 @Override
1402 public boolean isEmpty() {
1403 return ConcurrentIdentityHashMap.this.isEmpty();
1404 }
1405
1406 @Override
1407 public void clear() {
1408 ConcurrentIdentityHashMap.this.clear();
1409 }
1410 }
1411 }