ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
Revision: 1.69
Committed: Wed May 18 18:15:01 2005 UTC (19 years ago) by jsr166
Branch: MAIN
Changes since 1.68: +2 -2 lines
Log Message:
remove(x,null) -> false

File Contents

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