查看本类的 API文档回源码主页即时通讯网 - 即时通讯开发者社区!
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.ConcurrentHashMap;
36  import java.util.concurrent.ConcurrentMap;
37  import java.util.concurrent.locks.ReentrantLock;
38  
39  
40  /**
41   * An alternative identity-comparing {@link ConcurrentMap} which is similar to
42   * {@link ConcurrentHashMap}.
43   * @param <K> the type of keys maintained by this map
44   * @param <V> the type of mapped values
45   */
46  public final class ConcurrentIdentityHashMap<K, V> extends AbstractMap<K, V>
47          implements ConcurrentMap<K, V> {
48  
49      /**
50       * The default initial capacity for this table, used when not otherwise
51       * specified in a constructor.
52       */
53      static final int DEFAULT_INITIAL_CAPACITY = 16;
54  
55      /**
56       * The default load factor for this table, used when not otherwise specified
57       * in a constructor.
58       */
59      static final float DEFAULT_LOAD_FACTOR = 0.75f;
60  
61      /**
62       * The default concurrency level for this table, used when not otherwise
63       * specified in a constructor.
64       */
65      static final int DEFAULT_CONCURRENCY_LEVEL = 16;
66  
67      /**
68       * The maximum capacity, used if a higher value is implicitly specified by
69       * either of the constructors with arguments.  MUST be a power of two
70       * &lt;= 1&lt;&lt;30 to ensure that entries are indexable using integers.
71       */
72      static final int MAXIMUM_CAPACITY = 1 << 30;
73  
74      /**
75       * The maximum number of segments to allow; used to bound constructor
76       * arguments.
77       */
78      static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
79  
80      /**
81       * Number of unsynchronized retries in size and containsValue methods before
82       * resorting to locking. This is used to avoid unbounded retries if tables
83       * undergo continuous modification which would make it impossible to obtain
84       * an accurate result.
85       */
86      static final int RETRIES_BEFORE_LOCK = 2;
87  
88      /* ---------------- Fields -------------- */
89  
90      /**
91       * Mask value for indexing into segments. The upper bits of a key's hash
92       * code are used to choose the segment.
93       */
94      final int segmentMask;
95  
96      /**
97       * Shift value for indexing within segments.
98       */
99      final int segmentShift;
100 
101     /**
102      * The segments, each of which is a specialized hash table
103      */
104     final Segment<K, V>[] segments;
105 
106     Set<K> keySet;
107     Set<Map.Entry<K, V>> entrySet;
108     Collection<V> values;
109 
110     /* ---------------- Small Utilities -------------- */
111 
112     /**
113      * Applies a supplemental hash function to a given hashCode, which defends
114      * against poor quality hash functions.  This is critical because
115      * ConcurrentReferenceHashMap uses power-of-two length hash tables, that
116      * otherwise encounter collisions for hashCodes that do not differ in lower
117      * or upper bits.
118      */
119     private static int hash(int h) {
120         // Spread bits to regularize both segment and index locations,
121         // using variant of single-word Wang/Jenkins hash.
122         h += h << 15 ^ 0xffffcd7d;
123         h ^= h >>> 10;
124         h += h << 3;
125         h ^= h >>> 6;
126         h += (h << 2) + (h << 14);
127         return h ^ h >>> 16;
128     }
129 
130     /**
131      * Returns the segment that should be used for key with given hash.
132      *
133      * @param hash the hash code for the key
134      * @return the segment
135      */
136     Segment<K, V> segmentFor(int hash) {
137         return segments[hash >>> segmentShift & segmentMask];
138     }
139 
140     private static int hashOf(Object key) {
141         return hash(System.identityHashCode(key));
142     }
143 
144     /**
145      * ConcurrentReferenceHashMap list entry. Note that this is never exported
146      * out as a user-visible Map.Entry.
147      *
148      * Because the value field is volatile, not final, it is legal wrt
149      * the Java Memory Model for an unsynchronized reader to see null
150      * instead of initial value when read via a data race.  Although a
151      * reordering leading to this is not likely to ever actually
152      * occur, the Segment.readValueUnderLock method is used as a
153      * backup in case a null (pre-initialized) value is ever seen in
154      * an unsynchronized access method.
155      */
156     static final class HashEntry<K, V> {
157         final Object key;
158         final int hash;
159         volatile Object value;
160         final HashEntry<K, V> next;
161 
162         HashEntry(
163                 K key, int hash, HashEntry<K, V> next, V value) {
164             this.hash = hash;
165             this.next = next;
166             this.key = key;
167             this.value = value;
168         }
169 
170         @SuppressWarnings("unchecked")
171         K key() {
172             return (K) key;
173         }
174 
175         @SuppressWarnings("unchecked")
176         V value() {
177             return (V) value;
178         }
179 
180         void setValue(V value) {
181             this.value = value;
182         }
183 
184         @SuppressWarnings("unchecked")
185         static <K, V> HashEntry<K, V>[] newArray(int i) {
186             return new HashEntry[i];
187         }
188     }
189 
190     /**
191      * Segments are specialized versions of hash tables.  This subclasses from
192      * ReentrantLock opportunistically, just to simplify some locking and avoid
193      * separate construction.
194      */
195     static final class Segment<K, V> extends ReentrantLock {
196         /*
197          * Segments maintain a table of entry lists that are ALWAYS kept in a
198          * consistent state, so can be read without locking. Next fields of
199          * nodes are immutable (final).  All list additions are performed at the
200          * front of each bin. This makes it easy to check changes, and also fast
201          * to traverse. When nodes would otherwise be changed, new nodes are
202          * created to replace them. This works well for hash tables since the
203          * bin lists tend to be short. (The average length is less than two for
204          * the default load factor threshold.)
205          *
206          * Read operations can thus proceed without locking, but rely on
207          * selected uses of volatiles to ensure that completed write operations
208          * performed by other threads are noticed. For most purposes, the
209          * "count" field, tracking the number of elements, serves as that
210          * volatile variable ensuring visibility.  This is convenient because
211          * this field needs to be read in many read operations anyway:
212          *
213          *   - All (unsynchronized) read operations must first read the
214          *     "count" field, and should not look at table entries if
215          *     it is 0.
216          *
217          *   - All (synchronized) write operations should write to
218          *     the "count" field after structurally changing any bin.
219          *     The operations must not take any action that could even
220          *     momentarily cause a concurrent read operation to see
221          *     inconsistent data. This is made easier by the nature of
222          *     the read operations in Map. For example, no operation
223          *     can reveal that the table has grown but the threshold
224          *     has not yet been updated, so there are no atomicity
225          *     requirements for this with respect to reads.
226          *
227          * As a guide, all critical volatile reads and writes to the count field
228          * are marked in code comments.
229          */
230 
231         private static final long serialVersionUID = 5207829234977119743L;
232 
233         /**
234          * The number of elements in this segment's region.
235          */
236         transient volatile int count;
237 
238         /**
239          * Number of updates that alter the size of the table. This is used
240          * during bulk-read methods to make sure they see a consistent snapshot:
241          * If modCounts change during a traversal of segments computing size or
242          * checking containsValue, then we might have an inconsistent view of
243          * state so (usually) must retry.
244          */
245         int modCount;
246 
247         /**
248          * The table is rehashed when its size exceeds this threshold.
249          * (The value of this field is always <tt>(capacity * loadFactor)</tt>.)
250          */
251         int threshold;
252 
253         /**
254          * The per-segment table.
255          */
256         transient volatile HashEntry<K, V>[] table;
257 
258         /**
259          * The load factor for the hash table.  Even though this value is same
260          * for all segments, it is replicated to avoid needing links to outer
261          * object.
262          */
263         final float loadFactor;
264 
265         Segment(int initialCapacity, float lf) {
266             loadFactor = lf;
267             setTable(HashEntry.<K, V>newArray(initialCapacity));
268         }
269 
270         @SuppressWarnings("unchecked")
271         static <K, V> Segment<K, V>[] newArray(int i) {
272             return new Segment[i];
273         }
274 
275         private static boolean keyEq(Object src, Object dest) {
276             return src == dest;
277         }
278 
279         /**
280          * Sets table to new HashEntry array. Call only while holding lock or in
281          * constructor.
282          */
283         void setTable(HashEntry<K, V>[] newTable) {
284             threshold = (int) (newTable.length * loadFactor);
285             table = newTable;
286         }
287 
288         /**
289          * Returns properly casted first entry of bin for given hash.
290          */
291         HashEntry<K, V> getFirst(int hash) {
292             HashEntry<K, V>[] tab = table;
293             return tab[hash & tab.length - 1];
294         }
295 
296         HashEntry<K, V> newHashEntry(
297                 K key, int hash, HashEntry<K, V> next, V value) {
298             return new HashEntry<K, V>(key, hash, next, value);
299         }
300 
301         /**
302          * Reads value field of an entry under lock. Called if value field ever
303          * appears to be null. This is possible only if a compiler happens to
304          * reorder a HashEntry initialization with its table assignment, which
305          * is legal under memory model but is not known to ever occur.
306          */
307         V readValueUnderLock(HashEntry<K, V> e) {
308             lock();
309             try {
310                 return e.value();
311             } finally {
312                 unlock();
313             }
314         }
315 
316         /* Specialized implementations of map methods */
317 
318         V get(Object key, int hash) {
319             if (count != 0) { // read-volatile
320                 HashEntry<K, V>[] tab = table;
321                 HashEntry<K, V> e = tab[hash & tab.length - 1];
322                 if (tab != table) {
323                     return get(key, hash);
324                 }
325                 while (e != null) {
326                     if (e.hash == hash && keyEq(key, e.key())) {
327                         V opaque = e.value();
328                         if (opaque != null) {
329                             return opaque;
330                         }
331 
332                         return readValueUnderLock(e); // recheck
333                     }
334                     e = e.next;
335                 }
336             }
337             return null;
338         }
339 
340         boolean containsKey(Object key, int hash) {
341             if (count != 0) { // read-volatile
342                 HashEntry<K, V>[] tab = table;
343                 HashEntry<K, V> e = tab[hash & tab.length - 1];
344                 if (tab != table) {
345                     return containsKey(key, hash);
346                 }
347                 while (e != null) {
348                     if (e.hash == hash && keyEq(key, e.key())) {
349                         return true;
350                     }
351                     e = e.next;
352                 }
353             }
354             return false;
355         }
356 
357         boolean containsValue(Object value) {
358             if (count != 0) { // read-volatile
359                 HashEntry<K, V>[] tab = table;
360                 for (HashEntry<K, V> e: tab) {
361                     for (; e != null; e = e.next) {
362                         V opaque = e.value();
363                         V v;
364 
365                         if (opaque == null) {
366                             v = readValueUnderLock(e); // recheck
367                         } else {
368                             v = opaque;
369                         }
370 
371                         if (value.equals(v)) {
372                             return true;
373                         }
374                     }
375                 }
376                 if (table != tab) {
377                     return containsValue(value);
378                 }
379             }
380             return false;
381         }
382 
383         boolean replace(K key, int hash, V oldValue, V newValue) {
384             lock();
385             try {
386                 HashEntry<K, V> e = getFirst(hash);
387                 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
388                     e = e.next;
389                 }
390 
391                 boolean replaced = false;
392                 if (e != null && oldValue.equals(e.value())) {
393                     replaced = true;
394                     e.setValue(newValue);
395                 }
396                 return replaced;
397             } finally {
398                 unlock();
399             }
400         }
401 
402         V replace(K key, int hash, V newValue) {
403             lock();
404             try {
405                 HashEntry<K, V> e = getFirst(hash);
406                 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
407                     e = e.next;
408                 }
409 
410                 V oldValue = null;
411                 if (e != null) {
412                     oldValue = e.value();
413                     e.setValue(newValue);
414                 }
415                 return oldValue;
416             } finally {
417                 unlock();
418             }
419         }
420 
421         V put(K key, int hash, V value, boolean onlyIfAbsent) {
422             lock();
423             try {
424                 int c = count;
425                 if (c ++ > threshold) { // ensure capacity
426                     int reduced = rehash();
427                     if (reduced > 0) {
428                         count = (c -= reduced) - 1; // write-volatile
429                     }
430                 }
431 
432                 HashEntry<K, V>[] tab = table;
433                 int index = hash & tab.length - 1;
434                 HashEntry<K, V> first = tab[index];
435                 HashEntry<K, V> e = first;
436                 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
437                     e = e.next;
438                 }
439 
440                 V oldValue;
441                 if (e != null) {
442                     oldValue = e.value();
443                     if (!onlyIfAbsent) {
444                         e.setValue(value);
445                     }
446                 } else {
447                     oldValue = null;
448                     ++ modCount;
449                     tab[index] = newHashEntry(key, hash, first, value);
450                     count = c; // write-volatile
451                 }
452                 return oldValue;
453             } finally {
454                 unlock();
455             }
456         }
457 
458         int rehash() {
459             HashEntry<K, V>[] oldTable = table;
460             int oldCapacity = oldTable.length;
461             if (oldCapacity >= MAXIMUM_CAPACITY) {
462                 return 0;
463             }
464 
465             /*
466              * Reclassify nodes in each list to new Map.  Because we are using
467              * power-of-two expansion, the elements from each bin must either
468              * stay at same index, or move with a power of two offset. We
469              * eliminate unnecessary node creation by catching cases where old
470              * nodes can be reused because their next fields won't change.
471              * Statistically, at the default threshold, only about one-sixth of
472              * them need cloning when a table doubles. The nodes they replace
473              * will be garbage collectable as soon as they are no longer
474              * referenced by any reader thread that may be in the midst of
475              * traversing table right now.
476              */
477 
478             HashEntry<K, V>[] newTable = HashEntry.newArray(oldCapacity << 1);
479             threshold = (int) (newTable.length * loadFactor);
480             int sizeMask = newTable.length - 1;
481             int reduce = 0;
482             for (HashEntry<K, V> e: oldTable) {
483                 // We need to guarantee that any existing reads of old Map can
484                 // proceed. So we cannot yet null out each bin.
485                 if (e != null) {
486                     HashEntry<K, V> next = e.next;
487                     int idx = e.hash & sizeMask;
488 
489                     // Single node on list
490                     if (next == null) {
491                         newTable[idx] = e;
492                     } else {
493                         // Reuse trailing consecutive sequence at same slot
494                         HashEntry<K, V> lastRun = e;
495                         int lastIdx = idx;
496                         for (HashEntry<K, V> last = next; last != null; last = last.next) {
497                             int k = last.hash & sizeMask;
498                             if (k != lastIdx) {
499                                 lastIdx = k;
500                                 lastRun = last;
501                             }
502                         }
503                         newTable[lastIdx] = lastRun;
504                         // Clone all remaining nodes
505                         for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
506                             // Skip GC'd weak references
507                             K key = p.key();
508                             if (key == null) {
509                                 reduce++;
510                                 continue;
511                             }
512                             int k = p.hash & sizeMask;
513                             HashEntry<K, V> n = newTable[k];
514                             newTable[k] = newHashEntry(key, p.hash, n, p.value());
515                         }
516                     }
517                 }
518             }
519             table = newTable;
520             Arrays.fill(oldTable, null);
521             return reduce;
522         }
523 
524         /**
525          * Remove; match on key only if value null, else match both.
526          */
527         V remove(Object key, int hash, Object value, boolean refRemove) {
528             lock();
529             try {
530                 int c = count - 1;
531                 HashEntry<K, V>[] tab = table;
532                 int index = hash & tab.length - 1;
533                 HashEntry<K, V> first = tab[index];
534                 HashEntry<K, V> e = first;
535                 // a reference remove operation compares the Reference instance
536                 while (e != null && key != e.key &&
537                         (refRemove || hash != e.hash || !keyEq(key, e.key()))) {
538                     e = e.next;
539                 }
540 
541                 V oldValue = null;
542                 if (e != null) {
543                     V v = e.value();
544                     if (value == null || value.equals(v)) {
545                         oldValue = v;
546                         // All entries following removed node can stay in list,
547                         // but all preceding ones need to be cloned.
548                         ++ modCount;
549                         HashEntry<K, V> newFirst = e.next;
550                         for (HashEntry<K, V> p = first; p != e; p = p.next) {
551                             K pKey = p.key();
552                             if (pKey == null) { // Skip GC'd keys
553                                 c --;
554                                 continue;
555                             }
556 
557                             newFirst = newHashEntry(
558                                     pKey, p.hash, newFirst, p.value());
559                         }
560                         tab[index] = newFirst;
561                         count = c; // write-volatile
562                     }
563                 }
564                 return oldValue;
565             } finally {
566                 unlock();
567             }
568         }
569 
570         void clear() {
571             if (count != 0) {
572                 lock();
573                 try {
574                     HashEntry<K, V>[] tab = table;
575                     for (int i = 0; i < tab.length; i ++) {
576                         tab[i] = null;
577                     }
578                     ++ modCount;
579                     count = 0; // write-volatile
580                 } finally {
581                     unlock();
582                 }
583             }
584         }
585     }
586 
587     /* ---------------- Public operations -------------- */
588 
589     /**
590      * Creates a new, empty map with the specified initial capacity, load factor
591      * and concurrency level.
592      *
593      * @param initialCapacity the initial capacity. The implementation performs
594      *                        internal sizing to accommodate this many elements.
595      * @param loadFactor the load factor threshold, used to control resizing.
596      *                   Resizing may be performed when the average number of
597      *                   elements per bin exceeds this threshold.
598      * @param concurrencyLevel the estimated number of concurrently updating
599      *                         threads. The implementation performs internal
600      *                         sizing to try to accommodate this many threads.
601      * @throws IllegalArgumentException if the initial capacity is negative or
602      *                                  the load factor or concurrencyLevel are
603      *                                  nonpositive.
604      */
605     public ConcurrentIdentityHashMap(
606             int initialCapacity, float loadFactor,
607             int concurrencyLevel) {
608         if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) {
609             throw new IllegalArgumentException();
610         }
611 
612         if (concurrencyLevel > MAX_SEGMENTS) {
613             concurrencyLevel = MAX_SEGMENTS;
614         }
615 
616         // Find power-of-two sizes best matching arguments
617         int sshift = 0;
618         int ssize = 1;
619         while (ssize < concurrencyLevel) {
620             ++ sshift;
621             ssize <<= 1;
622         }
623         segmentShift = 32 - sshift;
624         segmentMask = ssize - 1;
625         segments = Segment.newArray(ssize);
626 
627         if (initialCapacity > MAXIMUM_CAPACITY) {
628             initialCapacity = MAXIMUM_CAPACITY;
629         }
630         int c = initialCapacity / ssize;
631         if (c * ssize < initialCapacity) {
632             ++ c;
633         }
634         int cap = 1;
635         while (cap < c) {
636             cap <<= 1;
637         }
638 
639         for (int i = 0; i < segments.length; ++ i) {
640             segments[i] = new Segment<K, V>(cap, loadFactor);
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         public SimpleEntry(Entry<? extends K, ? extends V> entry) {
1226             key = entry.getKey();
1227             value = entry.getValue();
1228         }
1229 
1230         public K getKey() {
1231             return key;
1232         }
1233 
1234         public V getValue() {
1235             return value;
1236         }
1237 
1238         public V setValue(V value) {
1239             V oldValue = this.value;
1240             this.value = value;
1241             return oldValue;
1242         }
1243 
1244         @Override
1245         public boolean equals(Object o) {
1246             if (!(o instanceof Map.Entry<?, ?>)) {
1247                 return false;
1248             }
1249             @SuppressWarnings("rawtypes")
1250             Map.Entry e = (Map.Entry) o;
1251             return eq(key, e.getKey()) && eq(value, e.getValue());
1252         }
1253 
1254         @Override
1255         public int hashCode() {
1256             return (key == null? 0 : key.hashCode()) ^ (value == null? 0 : value.hashCode());
1257         }
1258 
1259         @Override
1260         public String toString() {
1261             return key + "=" + value;
1262         }
1263 
1264         private static boolean eq(Object o1, Object o2) {
1265             return o1 == null? o2 == null : o1.equals(o2);
1266         }
1267     }
1268 
1269     /**
1270      * Custom Entry class used by EntryIterator.next(), that relays setValue
1271      * changes to the underlying map.
1272      */
1273     final class WriteThroughEntry extends SimpleEntry<K, V> {
1274 
1275         WriteThroughEntry(K k, V v) {
1276             super(k, v);
1277         }
1278 
1279         /**
1280          * Set our entry's value and write through to the map. The value to
1281          * return is somewhat arbitrary here. Since a WriteThroughEntry does not
1282          * necessarily track asynchronous changes, the most recent "previous"
1283          * value could be different from what we return (or could even have been
1284          * removed in which case the put will re-establish). We do not and can
1285          * not guarantee more.
1286          */
1287         @Override
1288         public V setValue(V value) {
1289 
1290             if (value == null) {
1291                 throw new NullPointerException();
1292             }
1293             V v = super.setValue(value);
1294             put(getKey(), value);
1295             return v;
1296         }
1297     }
1298 
1299     final class EntryIterator extends HashIterator implements
1300             ReusableIterator<Entry<K, V>> {
1301         public Map.Entry<K, V> next() {
1302             HashEntry<K, V> e = nextEntry();
1303             return new WriteThroughEntry(e.key(), e.value());
1304         }
1305     }
1306 
1307     final class KeySet extends AbstractSet<K> {
1308         @Override
1309         public Iterator<K> iterator() {
1310             return new KeyIterator();
1311         }
1312 
1313         @Override
1314         public int size() {
1315             return ConcurrentIdentityHashMap.this.size();
1316         }
1317 
1318         @Override
1319         public boolean isEmpty() {
1320             return ConcurrentIdentityHashMap.this.isEmpty();
1321         }
1322 
1323         @Override
1324         public boolean contains(Object o) {
1325             return containsKey(o);
1326         }
1327 
1328         @Override
1329         public boolean remove(Object o) {
1330             return ConcurrentIdentityHashMap.this.remove(o) != null;
1331         }
1332 
1333         @Override
1334         public void clear() {
1335             ConcurrentIdentityHashMap.this.clear();
1336         }
1337     }
1338 
1339     final class Values extends AbstractCollection<V> {
1340         @Override
1341         public Iterator<V> iterator() {
1342             return new ValueIterator();
1343         }
1344 
1345         @Override
1346         public int size() {
1347             return ConcurrentIdentityHashMap.this.size();
1348         }
1349 
1350         @Override
1351         public boolean isEmpty() {
1352             return ConcurrentIdentityHashMap.this.isEmpty();
1353         }
1354 
1355         @Override
1356         public boolean contains(Object o) {
1357             return containsValue(o);
1358         }
1359 
1360         @Override
1361         public void clear() {
1362             ConcurrentIdentityHashMap.this.clear();
1363         }
1364     }
1365 
1366     final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
1367         @Override
1368         public Iterator<Map.Entry<K, V>> iterator() {
1369             return new EntryIterator();
1370         }
1371 
1372         @Override
1373         public boolean contains(Object o) {
1374             if (!(o instanceof Map.Entry<?, ?>)) {
1375                 return false;
1376             }
1377             Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1378             V v = get(e.getKey());
1379             return v != null && v.equals(e.getValue());
1380         }
1381 
1382         @Override
1383         public boolean remove(Object o) {
1384             if (!(o instanceof Map.Entry<?, ?>)) {
1385                 return false;
1386             }
1387             Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
1388             return ConcurrentIdentityHashMap.this.remove(e.getKey(), e.getValue());
1389         }
1390 
1391         @Override
1392         public int size() {
1393             return ConcurrentIdentityHashMap.this.size();
1394         }
1395 
1396         @Override
1397         public boolean isEmpty() {
1398             return ConcurrentIdentityHashMap.this.isEmpty();
1399         }
1400 
1401         @Override
1402         public void clear() {
1403             ConcurrentIdentityHashMap.this.clear();
1404         }
1405     }
1406 }