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