ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
Revision: 1.1
Committed: Wed May 14 21:30:45 2003 UTC (21 years, 1 month ago) by tim
Branch: MAIN
Log Message:
Moved main source rooted at . to ./src/main
Moved test source rooted at ./etc/testcases to ./src/test

File Contents

# Content
1 package java.util.concurrent;
2
3 import java.util.*;
4 import java.io.Serializable;
5 import java.io.IOException;
6 import java.io.ObjectInputStream;
7 import java.io.ObjectOutputStream;
8
9 /**
10 * A version of Hashtable supporting
11 * concurrency for both retrievals and updates.
12 *
13 * <dl>
14 * <dt> Retrievals
15 *
16 * <dd> Retrievals may overlap updates. Successful retrievals using
17 * get(key) and containsKey(key) usually run without
18 * locking. Unsuccessful retrievals (i.e., when the key is not
19 * present) do involve brief synchronization (locking). Because
20 * retrieval operations can ordinarily overlap with update operations
21 * (i.e., put, remove, and their derivatives), retrievals can only be
22 * guaranteed to return the results of the most recently
23 * <em>completed</em> operations holding upon their onset. Retrieval
24 * operations may or may not return results reflecting in-progress
25 * writing operations. However, the retrieval operations do always
26 * return consistent results -- either those holding before any single
27 * modification or after it, but never a nonsense result. For
28 * aggregate operations such as putAll and clear, concurrent reads may
29 * reflect insertion or removal of only some entries. <p>
30 *
31 * Iterators and Enumerations (i.e., those returned by
32 * keySet().iterator(), entrySet().iterator(), values().iterator(),
33 * keys(), and elements()) return elements reflecting the state of the
34 * hash table at some point at or since the creation of the
35 * iterator/enumeration. They will return at most one instance of
36 * each element (via next()/nextElement()), but might or might not
37 * reflect puts and removes that have been processed since they were
38 * created. They do <em>not</em> throw ConcurrentModificationException.
39 * However, these iterators are designed to be used by only one
40 * thread at a time. Passing an iterator across multiple threads may
41 * lead to unpredictable results if the table is being concurrently
42 * modified. <p>
43 *
44 *
45 * <dt> Updates
46 *
47 * <dd> This class supports a hard-wired preset <em>concurrency
48 * level</em> of 32. This allows a maximum of 32 put and/or remove
49 * operations to proceed concurrently. This level is an upper bound on
50 * concurrency, not a guarantee, since it interacts with how
51 * well-strewn elements are across bins of the table. (The preset
52 * value in part reflects the fact that even on large multiprocessors,
53 * factors other than synchronization tend to be bottlenecks when more
54 * than 32 threads concurrently attempt updates.)
55 * Additionally, operations triggering internal resizing and clearing
56 * do not execute concurrently with any operation.
57 * <p>
58 *
59 * There is <em>NOT</em> any support for locking the entire table to
60 * prevent updates. This makes it imposssible, for example, to
61 * add an element only if it is not already present, since another
62 * thread may be in the process of doing the same thing.
63 *
64 * </dl>
65 *
66 *
67 * This class may be used as a direct replacement for
68 * java.util.Hashtable in any application that does not rely
69 * on the ability to lock the entire table to prevent updates.
70 * As of this writing, it performs much faster than Hashtable in
71 * typical multi-threaded applications with multiple readers and writers.
72 * Like Hashtable but unlike java.util.HashMap,
73 * this class does NOT allow <tt>null</tt> to be used as a key or
74 * value.
75 * <p>
76 *
77 *
78 **/
79 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
80 implements ConcurrentMap<K, V>, Cloneable, Serializable {
81
82 /*
83 The basic strategy is an optimistic-style scheme based on
84 the guarantee that the hash table and its lists are always
85 kept in a consistent enough state to be read without locking:
86
87 * Read operations first proceed without locking, by traversing the
88 apparently correct list of the apparently correct bin. If an
89 entry is found, but not invalidated (value field null), it is
90 returned. If not found, operations must recheck (after a memory
91 barrier) to make sure they are using both the right list and
92 the right table (which can change under resizes). If
93 invalidated, reads must acquire main update lock to wait out
94 the update, and then re-traverse.
95
96 * All list additions are at the front of each bin, making it easy
97 to check changes, and also fast to traverse. Entry next
98 pointers are never assigned. Remove() builds new nodes when
99 necessary to preserve this.
100
101 * Remove() (also clear()) invalidates removed nodes to alert read
102 operations that they must wait out the full modifications.
103
104 * Locking for puts, removes (and, when necessary gets, etc)
105 is controlled by Segments, each covering a portion of the
106 table. During operations requiring global exclusivity (mainly
107 resize and clear), ALL of these locks are acquired at once.
108 Note that these segments are NOT contiguous -- they are based
109 on the least 5 bits of hashcodes. This ensures that the same
110 segment controls the same slots before and after resizing, which
111 is necessary for supporting concurrent retrievals. This
112 comes at the price of a mismatch of logical vs physical locality,
113 but this seems not to be a performance problem in practice.
114
115 */
116
117 /**
118 * The hash table data.
119 */
120 private transient Entry<K,V>[] table;
121
122
123 /**
124 * The number of concurrency control segments.
125 * The value can be at most 32 since ints are used
126 * as bitsets over segments. Emprically, it doesn't
127 * seem to pay to decrease it either, so the value should be at least 32.
128 * In other words, do not redefine this :-)
129 **/
130 private static final int CONCURRENCY_LEVEL = 32;
131
132 /**
133 * Mask value for indexing into segments
134 **/
135 private static final int SEGMENT_MASK = CONCURRENCY_LEVEL - 1;
136
137 /**
138 * Bookkeeping for each concurrency control segment.
139 * Each segment contains a local count of the number of
140 * elements in its region.
141 * However, the main use of a Segment is for its lock.
142 **/
143 private final static class Segment {
144 /**
145 * The number of elements in this segment's region.
146 * It is always updated within synchronized blocks.
147 **/
148 private int count;
149
150 /**
151 * Get the count under synch.
152 **/
153 private synchronized int getCount() { return count; }
154
155 /**
156 * Force a synchronization
157 **/
158 private synchronized void synch() {}
159 }
160
161 /**
162 * The array of concurrency control segments.
163 **/
164 private final Segment[] segments = new Segment[CONCURRENCY_LEVEL];
165
166
167 /**
168 * The default initial number of table slots for this table (32).
169 * Used when not otherwise specified in constructor.
170 **/
171 public static int DEFAULT_INITIAL_CAPACITY = 32;
172
173
174 /**
175 * The minimum capacity, used if a lower value is implicitly specified
176 * by either of the constructors with arguments.
177 * MUST be a power of two.
178 */
179 private static final int MINIMUM_CAPACITY = 32;
180
181 /**
182 * The maximum capacity, used if a higher value is implicitly specified
183 * by either of the constructors with arguments.
184 * MUST be a power of two <= 1<<30.
185 */
186 private static final int MAXIMUM_CAPACITY = 1 << 30;
187
188 /**
189 * The default load factor for this table (0.75)
190 * Used when not otherwise specified in constructor.
191 **/
192 public static final float DEFAULT_LOAD_FACTOR = 0.75f;
193
194 /**
195 * The load factor for the hash table.
196 *
197 * @serial
198 */
199 private final float loadFactor;
200
201 /**
202 * Per-segment resize threshold.
203 *
204 * @serial
205 */
206 private int threshold;
207
208
209 /**
210 * Number of segments voting for resize. The table is
211 * doubled when 1/4 of the segments reach threshold.
212 * Volatile but updated without synch since this is just a heuristic.
213 **/
214 private transient volatile int votesForResize;
215
216
217 /**
218 * Return the number of set bits in w.
219 * For a derivation of this algorithm, see
220 * "Algorithms and data structures with applications to
221 * graphics and geometry", by Jurg Nievergelt and Klaus Hinrichs,
222 * Prentice Hall, 1993.
223 * See also notes by Torsten Sillke at
224 * http://www.mathematik.uni-bielefeld.de/~sillke/PROBLEMS/bitcount
225 **/
226 private static int bitcount(int w) {
227 w -= (0xaaaaaaaa & w) >>> 1;
228 w = (w & 0x33333333) + ((w >>> 2) & 0x33333333);
229 w = (w + (w >>> 4)) & 0x0f0f0f0f;
230 w += w >>> 8;
231 w += w >>> 16;
232 return w & 0xff;
233 }
234
235 /**
236 * Returns the appropriate capacity (power of two) for the specified
237 * initial capacity argument.
238 */
239 private int p2capacity(int initialCapacity) {
240 int cap = initialCapacity;
241
242 // Compute the appropriate capacity
243 int result;
244 if (cap > MAXIMUM_CAPACITY || cap < 0) {
245 result = MAXIMUM_CAPACITY;
246 } else {
247 result = MINIMUM_CAPACITY;
248 while (result < cap)
249 result <<= 1;
250 }
251 return result;
252 }
253
254 /**
255 * Return hash code for Object x. Since we are using power-of-two
256 * tables, it is worth the effort to improve hashcode via
257 * the same multiplicative scheme as used in IdentityHashMap.
258 */
259 private static int hash(Object x) {
260 int h = x.hashCode();
261 // Multiply by 127 (quickly, via shifts), and mix in some high
262 // bits to help guard against bunching of codes that are
263 // consecutive or equally spaced.
264 return ((h << 7) - h + (h >>> 9) + (h >>> 17));
265 }
266
267
268 /**
269 * Check for equality of non-null references x and y.
270 **/
271 private boolean eq(Object x, Object y) {
272 return x == y || x.equals(y);
273 }
274
275 /** Create table array and set the per-segment threshold **/
276 private Entry<K,V>[] newTable(int capacity) {
277 threshold = (int)(capacity * loadFactor / CONCURRENCY_LEVEL) + 1;
278 return new Entry<K,V>[capacity];
279 }
280
281 /**
282 * Constructs a new, empty map with the specified initial
283 * capacity and the specified load factor.
284 *
285 * @param initialCapacity the initial capacity.
286 * The actual initial capacity is rounded up to the nearest power of two.
287 * @param loadFactor the load factor threshold, used to control resizing.
288 * This value is used in an approximate way: When at least
289 * a quarter of the segments of the table reach per-segment threshold, or
290 * one of the segments itself exceeds overall threshold,
291 * the table is doubled.
292 * This will on average cause resizing when the table-wide
293 * load factor is slightly less than the threshold. If you'd like
294 * to avoid resizing, you can set this to a ridiculously large
295 * value.
296 * @throws IllegalArgumentException if the load factor is nonpositive.
297 */
298 public ConcurrentHashMap(int initialCapacity, float loadFactor) {
299 if (!(loadFactor > 0))
300 throw new IllegalArgumentException("Illegal Load factor: "+ loadFactor);
301 this.loadFactor = loadFactor;
302 for (int i = 0; i < segments.length; ++i)
303 segments[i] = new Segment();
304 int cap = p2capacity(initialCapacity);
305 table = newTable(cap);
306 }
307
308 /**
309 * Constructs a new, empty map with the specified initial
310 * capacity and default load factor.
311 *
312 * @param initialCapacity the initial capacity of the
313 * ConcurrentHashMap.
314 * @throws IllegalArgumentException if the initial maximum number
315 * of elements is less
316 * than zero.
317 */
318 public ConcurrentHashMap(int initialCapacity) {
319 this(initialCapacity, DEFAULT_LOAD_FACTOR);
320 }
321
322 /**
323 * Constructs a new, empty map with a default initial capacity
324 * and default load factor.
325 */
326 public ConcurrentHashMap() {
327 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
328 }
329
330 /**
331 * Constructs a new map with the same mappings as the given map. The
332 * map is created with a capacity of twice the number of mappings in
333 * the given map or 32 (whichever is greater), and a default load factor.
334 */
335 public <A extends K, B extends V> ConcurrentHashMap(Map<A,B> t) {
336 this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
337 MINIMUM_CAPACITY),
338 DEFAULT_LOAD_FACTOR);
339 putAll(t);
340 }
341
342 /**
343 * Returns the number of key-value mappings in this map.
344 *
345 * @return the number of key-value mappings in this map.
346 */
347 public int size() {
348 int c = 0;
349 for (int i = 0; i < segments.length; ++i)
350 c += segments[i].getCount();
351 return c;
352 }
353
354 /**
355 * Returns <tt>true</tt> if this map contains no key-value mappings.
356 *
357 * @return <tt>true</tt> if this map contains no key-value mappings.
358 */
359 public boolean isEmpty() {
360 for (int i = 0; i < segments.length; ++i)
361 if (segments[i].getCount() != 0)
362 return false;
363 return true;
364 }
365
366
367 /**
368 * Returns the value to which the specified key is mapped in this table.
369 *
370 * @param key a key in the table.
371 * @return the value to which the key is mapped in this table;
372 * <code>null</code> if the key is not mapped to any value in
373 * this table.
374 * @exception NullPointerException if the key is
375 * <code>null</code>.
376 * @see #put(Object, Object)
377 */
378 public V get(Object key) {
379 int hash = hash(key); // throws null pointer exception if key null
380
381 // Try first without locking...
382 Entry<K,V>[] tab = table;
383 int index = hash & (tab.length - 1);
384 Entry<K,V> first = tab[index];
385 Entry<K,V> e;
386
387 for (e = first; e != null; e = e.next) {
388 if (e.hash == hash && eq(key, e.key)) {
389 V value = e.value;
390 if (value != null)
391 return value;
392 else
393 break;
394 }
395 }
396
397 // Recheck under synch if key apparently not there or interference
398 Segment seg = segments[hash & SEGMENT_MASK];
399 synchronized(seg) {
400 tab = table;
401 index = hash & (tab.length - 1);
402 Entry<K,V> newFirst = tab[index];
403 if (e != null || first != newFirst) {
404 for (e = newFirst; e != null; e = e.next) {
405 if (e.hash == hash && eq(key, e.key))
406 return e.value;
407 }
408 }
409 return null;
410 }
411 }
412
413 /**
414 * Tests if the specified object is a key in this table.
415 *
416 * @param key possible key.
417 * @return <code>true</code> if and only if the specified object
418 * is a key in this table, as determined by the
419 * <tt>equals</tt> method; <code>false</code> otherwise.
420 * @exception NullPointerException if the key is
421 * <code>null</code>.
422 * @see #contains(Object)
423 */
424 public boolean containsKey(Object key) {
425 return get(key) != null;
426 }
427
428
429 /**
430 * Maps the specified <code>key</code> to the specified
431 * <code>value</code> in this table. Neither the key nor the
432 * value can be <code>null</code>. (Note that this policy is
433 * the same as for java.util.Hashtable, but unlike java.util.HashMap,
434 * which does accept nulls as valid keys and values.)<p>
435 *
436 * The value can be retrieved by calling the <code>get</code> method
437 * with a key that is equal to the original key.
438 *
439 * @param key the table key.
440 * @param value the value.
441 * @return the previous value of the specified key in this table,
442 * or <code>null</code> if it did not have one.
443 * @exception NullPointerException if the key or value is
444 * <code>null</code>.
445 * @see Object#equals(Object)
446 * @see #get(Object)
447 */
448 public V put(K key, V value) {
449 if (value == null)
450 throw new NullPointerException();
451
452 int hash = hash(key);
453 Segment seg = segments[hash & SEGMENT_MASK];
454 int segcount;
455 Entry<K,V>[] tab;
456 int votes;
457
458 synchronized(seg) {
459 tab = table;
460 int index = hash & (tab.length-1);
461 Entry<K,V> first = tab[index];
462
463 for (Entry<K,V> e = first; e != null; e = e.next) {
464 if (e.hash == hash && eq(key, e.key)) {
465 V oldValue = e.value;
466 e.value = value;
467 return oldValue;
468 }
469 }
470
471 // Add to front of list
472 Entry<K,V> newEntry = new Entry<K,V>(hash, key, value, first);
473 tab[index] = newEntry;
474
475 if ((segcount = ++seg.count) < threshold)
476 return null;
477
478 int bit = (1 << (hash & SEGMENT_MASK));
479 votes = votesForResize;
480 if ((votes & bit) == 0)
481 votes = votesForResize |= bit;
482 }
483
484 // Attempt resize if 1/4 segs vote,
485 // or if this seg itself reaches the overall threshold.
486 // (The latter check is just a safeguard to avoid pathological cases.)
487 if (bitcount(votes) >= CONCURRENCY_LEVEL / 4 ||
488 segcount > (threshold * CONCURRENCY_LEVEL))
489 resize(0, tab);
490
491 return null;
492 }
493
494 public V putIfAbsent(K key, V value) {
495 if (value == null)
496 throw new NullPointerException();
497
498 int hash = hash(key);
499 Segment seg = segments[hash & SEGMENT_MASK];
500 int segcount;
501 Entry<K,V>[] tab;
502 int votes;
503
504 synchronized(seg) {
505 tab = table;
506 int index = hash & (tab.length-1);
507 Entry<K,V> first = tab[index];
508
509 for (Entry<K,V> e = first; e != null; e = e.next) {
510 if (e.hash == hash && eq(key, e.key)) {
511 V oldValue = e.value;
512 return oldValue;
513 }
514 }
515
516 // Add to front of list
517 Entry<K,V> newEntry = new Entry<K,V>(hash, key, value, first);
518 tab[index] = newEntry;
519
520 if ((segcount = ++seg.count) < threshold)
521 return null;
522
523 int bit = (1 << (hash & SEGMENT_MASK));
524 votes = votesForResize;
525 if ((votes & bit) == 0)
526 votes = votesForResize |= bit;
527 }
528
529 // Attempt resize if 1/4 segs vote,
530 // or if this seg itself reaches the overall threshold.
531 // (The latter check is just a safeguard to avoid pathological cases.)
532 if (bitcount(votes) >= CONCURRENCY_LEVEL / 4 ||
533 segcount > (threshold * CONCURRENCY_LEVEL))
534 resize(0, tab);
535
536 return value;
537 }
538
539 /**
540 * Gather all locks in order to call rehash, by
541 * recursing within synch blocks for each segment index.
542 * @param index the current segment. initially call value must be 0
543 * @param assumedTab the state of table on first call to resize. If
544 * this changes on any call, the attempt is aborted because the
545 * table has already been resized by another thread.
546 */
547 private void resize(int index, Entry<K,V>[] assumedTab) {
548 Segment seg = segments[index];
549 synchronized(seg) {
550 if (assumedTab == table) {
551 int next = index+1;
552 if (next < segments.length)
553 resize(next, assumedTab);
554 else
555 rehash();
556 }
557 }
558 }
559
560 /**
561 * Rehashes the contents of this map into a new table
562 * with a larger capacity.
563 */
564 private void rehash() {
565 votesForResize = 0; // reset
566
567 Entry<K,V>[] oldTable = table;
568 int oldCapacity = oldTable.length;
569
570 if (oldCapacity >= MAXIMUM_CAPACITY) {
571 threshold = Integer.MAX_VALUE; // avoid retriggering
572 return;
573 }
574
575 int newCapacity = oldCapacity << 1;
576 Entry<K,V>[] newTable = newTable(newCapacity);
577 int mask = newCapacity - 1;
578
579 /*
580 * Reclassify nodes in each list to new Map. Because we are
581 * using power-of-two expansion, the elements from each bin
582 * must either stay at same index, or move to
583 * oldCapacity+index. We also eliminate unnecessary node
584 * creation by catching cases where old nodes can be reused
585 * because their next fields won't change. Statistically, at
586 * the default threshhold, only about one-sixth of them need
587 * cloning. (The nodes they replace will be garbage
588 * collectable as soon as they are no longer referenced by any
589 * reader thread that may be in the midst of traversing table
590 * right now.)
591 */
592
593 for (int i = 0; i < oldCapacity ; i++) {
594 // We need to guarantee that any existing reads of old Map can
595 // proceed. So we cannot yet null out each bin.
596 Entry<K,V> e = oldTable[i];
597
598 if (e != null) {
599 int idx = e.hash & mask;
600 Entry<K,V> next = e.next;
601
602 // Single node on list
603 if (next == null)
604 newTable[idx] = e;
605
606 else {
607 // Reuse trailing consecutive sequence of all same bit
608 Entry<K,V> lastRun = e;
609 int lastIdx = idx;
610 for (Entry<K,V> last = next; last != null; last = last.next) {
611 int k = last.hash & mask;
612 if (k != lastIdx) {
613 lastIdx = k;
614 lastRun = last;
615 }
616 }
617 newTable[lastIdx] = lastRun;
618
619 // Clone all remaining nodes
620 for (Entry<K,V> p = e; p != lastRun; p = p.next) {
621 int k = p.hash & mask;
622 newTable[k] = new Entry<K,V>(p.hash, p.key,
623 p.value, newTable[k]);
624 }
625 }
626 }
627 }
628
629 table = newTable;
630 }
631
632
633 /**
634 * Removes the key (and its corresponding value) from this
635 * table. This method does nothing if the key is not in the table.
636 *
637 * @param key the key that needs to be removed.
638 * @return the value to which the key had been mapped in this table,
639 * or <code>null</code> if the key did not have a mapping.
640 * @exception NullPointerException if the key is
641 * <code>null</code>.
642 */
643 public V remove(Object key) {
644 return remove(key, null);
645 }
646
647
648 /**
649 * Removes the (key, value) pair from this
650 * table. This method does nothing if the key is not in the table,
651 * or if the key is associated with a different value. This method
652 * is needed by EntrySet.
653 *
654 * @param key the key that needs to be removed.
655 * @param value the associated value. If the value is null,
656 * it means "any value".
657 * @return the value to which the key had been mapped in this table,
658 * or <code>null</code> if the key did not have a mapping.
659 * @exception NullPointerException if the key is
660 * <code>null</code>.
661 */
662 private V remove(Object key, V value) {
663 /*
664 Find the entry, then
665 1. Set value field to null, to force get() to retry
666 2. Rebuild the list without this entry.
667 All entries following removed node can stay in list, but
668 all preceeding ones need to be cloned. Traversals rely
669 on this strategy to ensure that elements will not be
670 repeated during iteration.
671 */
672
673 int hash = hash(key);
674 Segment seg = segments[hash & SEGMENT_MASK];
675
676 synchronized(seg) {
677 Entry<K,V>[] tab = table;
678 int index = hash & (tab.length-1);
679 Entry<K,V> first = tab[index];
680 Entry<K,V> e = first;
681
682 for (;;) {
683 if (e == null)
684 return null;
685 if (e.hash == hash && eq(key, e.key))
686 break;
687 e = e.next;
688 }
689
690 V oldValue = e.value;
691 if (value != null && !value.equals(oldValue))
692 return null;
693
694 e.value = null;
695
696 Entry<K,V> head = e.next;
697 for (Entry<K,V> p = first; p != e; p = p.next)
698 head = new Entry<K,V>(p.hash, p.key, p.value, head);
699 tab[index] = head;
700 seg.count--;
701 return oldValue;
702 }
703 }
704
705
706 /**
707 * Returns <tt>true</tt> if this map maps one or more keys to the
708 * specified value. Note: This method requires a full internal
709 * traversal of the hash table, and so is much slower than
710 * method <tt>containsKey</tt>.
711 *
712 * @param value value whose presence in this map is to be tested.
713 * @return <tt>true</tt> if this map maps one or more keys to the
714 * specified value.
715 * @exception NullPointerException if the value is <code>null</code>.
716 */
717 public boolean containsValue(Object value) {
718
719 if (value == null) throw new NullPointerException();
720
721 for (int s = 0; s < segments.length; ++s) {
722 Segment seg = segments[s];
723 Entry<K,V>[] tab;
724 synchronized(seg) { tab = table; }
725 for (int i = s; i < tab.length; i+= segments.length) {
726 for (Entry<K,V> e = tab[i]; e != null; e = e.next)
727 if (value.equals(e.value))
728 return true;
729 }
730 }
731 return false;
732 }
733
734 /**
735 * Tests if some key maps into the specified value in this table.
736 * This operation is more expensive than the <code>containsKey</code>
737 * method.<p>
738 *
739 * Note that this method is identical in functionality to containsValue,
740 * (which is part of the Map interface in the collections framework).
741 *
742 * @param value a value to search for.
743 * @return <code>true</code> if and only if some key maps to the
744 * <code>value</code> argument in this table as
745 * determined by the <tt>equals</tt> method;
746 * <code>false</code> otherwise.
747 * @exception NullPointerException if the value is <code>null</code>.
748 * @see #containsKey(Object)
749 * @see #containsValue(Object)
750 * @see Map
751 */
752 public boolean contains(V value) {
753 return containsValue(value);
754 }
755
756 /**
757 * Copies all of the mappings from the specified map to this one.
758 *
759 * These mappings replace any mappings that this map had for any of the
760 * keys currently in the specified Map.
761 *
762 * @param t Mappings to be stored in this map.
763 */
764 public <A extends K, B extends V> void putAll(Map<A, B> t) {
765 int n = t.size();
766 if (n == 0)
767 return;
768
769 // Expand enough to hold at least n elements without resizing.
770 // We can only resize table by factor of two at a time.
771 // It is faster to rehash with fewer elements, so do it now.
772 for(;;) {
773 Entry<K,V>[] tab;
774 int max;
775 synchronized(segments[0]) { // must synch on some segment. pick 0.
776 tab = table;
777 max = threshold * CONCURRENCY_LEVEL;
778 }
779 if (n < max)
780 break;
781 resize(0, tab);
782 }
783
784 for (Iterator<Map.Entry<A,B>> it = t.entrySet().iterator(); it.hasNext();) {
785 Map.Entry<A,B> entry = (Map.Entry<A,B>) it.next();
786 put(entry.getKey(), entry.getValue());
787 }
788 }
789
790 /**
791 * Removes all mappings from this map.
792 */
793 public void clear() {
794 // We don't need all locks at once so long as locks
795 // are obtained in low to high order
796 for (int s = 0; s < segments.length; ++s) {
797 Segment seg = segments[s];
798 synchronized(seg) {
799 Entry<K,V>[] tab = table;
800 for (int i = s; i < tab.length; i+= segments.length) {
801 for (Entry<K,V> e = tab[i]; e != null; e = e.next)
802 e.value = null;
803 tab[i] = null;
804 seg.count = 0;
805 }
806 }
807 }
808 }
809
810 /**
811 * Returns a shallow copy of this
812 * <tt>ConcurrentHashMap</tt> instance: the keys and
813 * values themselves are not cloned.
814 *
815 * @return a shallow copy of this map.
816 */
817 public Object clone() {
818 // We cannot call super.clone, since it would share final segments array,
819 // and there's no way to reassign finals.
820 return new ConcurrentHashMap<K,V>(this);
821 }
822
823 // Views
824
825 private transient Set<K> keySet = null;
826 private transient Set<Map.Entry<K,V>> entrySet = null;
827 private transient Collection<V> values = null;
828
829 /**
830 * Returns a set view of the keys contained in this map. The set is
831 * backed by the map, so changes to the map are reflected in the set, and
832 * vice-versa. The set supports element removal, which removes the
833 * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
834 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
835 * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
836 * <tt>addAll</tt> operations.
837 *
838 * @return a set view of the keys contained in this map.
839 */
840 public Set<K> keySet() {
841 Set<K> ks = keySet;
842 return (ks != null)? ks : (keySet = new KeySet());
843 }
844
845 private class KeySet extends AbstractSet<K> {
846 public Iterator<K> iterator() {
847 return new KeyIterator();
848 }
849 public int size() {
850 return ConcurrentHashMap.this.size();
851 }
852 public boolean contains(Object o) {
853 return ConcurrentHashMap.this.containsKey(o);
854 }
855 public boolean remove(Object o) {
856 return ConcurrentHashMap.this.remove(o) != null;
857 }
858 public void clear() {
859 ConcurrentHashMap.this.clear();
860 }
861 }
862
863 /**
864 * Returns a collection view of the values contained in this map. The
865 * collection is backed by the map, so changes to the map are reflected in
866 * the collection, and vice-versa. The collection supports element
867 * removal, which removes the corresponding mapping from this map, via the
868 * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
869 * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
870 * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
871 *
872 * @return a collection view of the values contained in this map.
873 */
874 public Collection<V> values() {
875 Collection<V> vs = values;
876 return (vs != null)? vs : (values = new Values());
877 }
878
879 private class Values extends AbstractCollection<V> {
880 public Iterator<V> iterator() {
881 return new ValueIterator();
882 }
883 public int size() {
884 return ConcurrentHashMap.this.size();
885 }
886 public boolean contains(Object o) {
887 return ConcurrentHashMap.this.containsValue(o);
888 }
889 public void clear() {
890 ConcurrentHashMap.this.clear();
891 }
892 }
893
894 /**
895 * Returns a collection view of the mappings contained in this map. Each
896 * element in the returned collection is a <tt>Map.Entry</tt>. The
897 * collection is backed by the map, so changes to the map are reflected in
898 * the collection, and vice-versa. The collection supports element
899 * removal, which removes the corresponding mapping from the map, via the
900 * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
901 * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
902 * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
903 *
904 * @return a collection view of the mappings contained in this map.
905 */
906 public Set<Map.Entry<K,V>> entrySet() {
907 Set<Map.Entry<K,V>> es = entrySet;
908 return (es != null) ? es : (entrySet = new EntrySet());
909 }
910
911 private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
912 public Iterator<Map.Entry<K,V>> iterator() {
913 return new EntryIterator();
914 }
915 public boolean contains(Map.Entry<K,V> entry) {
916 V v = ConcurrentHashMap.this.get(entry.getKey());
917 return v != null && v.equals(entry.getValue());
918 }
919 public boolean remove(Map.Entry<K,V> e) {
920 return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()) != null;
921 }
922 public int size() {
923 return ConcurrentHashMap.this.size();
924 }
925 public void clear() {
926 ConcurrentHashMap.this.clear();
927 }
928 }
929
930 /**
931 * Returns an enumeration of the keys in this table.
932 *
933 * @return an enumeration of the keys in this table.
934 * @see Enumeration
935 * @see #elements()
936 * @see #keySet()
937 * @see Map
938 */
939 public Enumeration keys() {
940 return new KeyIterator();
941 }
942
943 /**
944 * Returns an enumeration of the values in this table.
945 * Use the Enumeration methods on the returned object to fetch the elements
946 * sequentially.
947 *
948 * @return an enumeration of the values in this table.
949 * @see java.util.Enumeration
950 * @see #keys()
951 * @see #values()
952 * @see Map
953 */
954 public Enumeration elements() {
955 return new ValueIterator();
956 }
957
958 /**
959 * ConcurrentHashMap collision list entry.
960 */
961 private static class Entry<K,V> implements Map.Entry<K,V> {
962 /*
963 The use of volatile for value field ensures that
964 we can detect status changes without synchronization.
965 The other fields are never changed, and are
966 marked as final.
967 */
968
969 private final K key;
970 private volatile V value;
971 private final int hash;
972 private final Entry<K,V> next;
973
974 Entry(int hash, K key, V value, Entry<K,V> next) {
975 this.value = value;
976 this.hash = hash;
977 this.key = key;
978 this.next = next;
979 }
980
981 // Map.Entry Ops
982
983 public K getKey() {
984 return key;
985 }
986
987 /**
988 * Get the value. Note: In an entrySet or entrySet.iterator,
989 * unless you can guarantee lack of concurrent modification,
990 * <tt>getValue</tt> <em>might</em> return null, reflecting the
991 * fact that the entry has been concurrently removed. However,
992 * there are no assurances that concurrent removals will be
993 * reflected using this method.
994 *
995 * @return the current value, or null if the entry has been
996 * detectably removed.
997 **/
998 public V getValue() {
999 return value;
1000 }
1001
1002 /**
1003 * Set the value of this entry. Note: In an entrySet or
1004 * entrySet.iterator), unless you can guarantee lack of concurrent
1005 * modification, <tt>setValue</tt> is not strictly guaranteed to
1006 * actually replace the value field obtained via the <tt>get</tt>
1007 * operation of the underlying hash table in multithreaded
1008 * applications. If iterator-wide synchronization is not used,
1009 * and any other concurrent <tt>put</tt> or <tt>remove</tt>
1010 * operations occur, sometimes even to <em>other</em> entries,
1011 * then this change is not guaranteed to be reflected in the hash
1012 * table. (It might, or it might not. There are no assurances
1013 * either way.)
1014 *
1015 * @param value the new value.
1016 * @return the previous value, or null if entry has been detectably
1017 * removed.
1018 * @exception NullPointerException if the value is <code>null</code>.
1019 *
1020 **/
1021 public V setValue(V value) {
1022 if (value == null)
1023 throw new NullPointerException();
1024 V oldValue = this.value;
1025 this.value = value;
1026 return oldValue;
1027 }
1028
1029 public boolean equals(Object o) {
1030 if (!(o instanceof Map.Entry))
1031 return false;
1032 Map.Entry e = (Map.Entry)o;
1033 return (key.equals(e.getKey()) && value.equals(e.getValue()));
1034 }
1035
1036 public int hashCode() {
1037 return key.hashCode() ^ value.hashCode();
1038 }
1039
1040 public String toString() {
1041 return key + "=" + value;
1042 }
1043
1044 }
1045
1046 private abstract class HashIterator<T> implements Iterator<T>, Enumeration {
1047 private final Entry<K,V>[] tab; // snapshot of table
1048 private int index; // current slot
1049 Entry<K,V> entry = null; // current node of slot
1050 K currentKey; // key for current node
1051 V currentValue; // value for current node
1052 private Entry lastReturned = null; // last node returned by next
1053
1054 private HashIterator() {
1055 // force all segments to synch
1056 synchronized(segments[0]) { tab = table; }
1057 for (int i = 1; i < segments.length; ++i) segments[i].synch();
1058 index = tab.length - 1;
1059 }
1060
1061 public boolean hasMoreElements() { return hasNext(); }
1062 public Object nextElement() { return next(); }
1063
1064 public boolean hasNext() {
1065 /*
1066 currentkey and currentValue are set here to ensure that next()
1067 returns normally if hasNext() returns true. This avoids
1068 surprises especially when final element is removed during
1069 traversal -- instead, we just ignore the removal during
1070 current traversal.
1071 */
1072
1073 while (true) {
1074 if (entry != null) {
1075 V v = entry.value;
1076 if (v != null) {
1077 currentKey = entry.key;
1078 currentValue = v;
1079 return true;
1080 }
1081 else
1082 entry = entry.next;
1083 }
1084
1085 while (entry == null && index >= 0)
1086 entry = tab[index--];
1087
1088 if (entry == null) {
1089 currentKey = null;
1090 currentValue = null;
1091 return false;
1092 }
1093 }
1094 }
1095
1096 abstract T returnValueOfNext();
1097
1098 public T next() {
1099 if (currentKey == null && !hasNext())
1100 throw new NoSuchElementException();
1101
1102 T result = returnValueOfNext();
1103 lastReturned = entry;
1104 currentKey = null;
1105 currentValue = null;
1106 entry = entry.next;
1107 return result;
1108 }
1109
1110 public void remove() {
1111 if (lastReturned == null)
1112 throw new IllegalStateException();
1113 ConcurrentHashMap.this.remove(lastReturned.key);
1114 lastReturned = null;
1115 }
1116
1117 }
1118
1119 private class KeyIterator extends HashIterator<K> {
1120 K returnValueOfNext() { return currentKey; }
1121 public K next() { return super.next(); }
1122 }
1123
1124 private class ValueIterator extends HashIterator<V> {
1125 V returnValueOfNext() { return currentValue; }
1126 public V next() { return super.next(); }
1127 }
1128
1129 private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
1130 Map.Entry<K,V> returnValueOfNext() { return entry; }
1131 public Map.Entry<K,V> next() { return super.next(); }
1132 }
1133
1134 /**
1135 * Save the state of the <tt>ConcurrentHashMap</tt>
1136 * instance to a stream (i.e.,
1137 * serialize it).
1138 *
1139 * @serialData
1140 * An estimate of the table size, followed by
1141 * the key (Object) and value (Object)
1142 * for each key-value mapping, followed by a null pair.
1143 * The key-value mappings are emitted in no particular order.
1144 */
1145 private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1146 // Write out the loadfactor, and any hidden stuff
1147 s.defaultWriteObject();
1148
1149 // Write out capacity estimate. It is OK if this
1150 // changes during the write, since it is only used by
1151 // readObject to set initial capacity, to avoid needless resizings.
1152
1153 int cap;
1154 synchronized(segments[0]) { cap = table.length; }
1155 s.writeInt(cap);
1156
1157 // Write out keys and values (alternating)
1158 for (int k = 0; k < segments.length; ++k) {
1159 Segment seg = segments[k];
1160 Entry[] tab;
1161 synchronized(seg) { tab = table; }
1162 for (int i = k; i < tab.length; i+= segments.length) {
1163 for (Entry e = tab[i]; e != null; e = e.next) {
1164 s.writeObject(e.key);
1165 s.writeObject(e.value);
1166 }
1167 }
1168 }
1169
1170 s.writeObject(null);
1171 s.writeObject(null);
1172 }
1173
1174 /**
1175 * Reconstitute the <tt>ConcurrentHashMap</tt>
1176 * instance from a stream (i.e.,
1177 * deserialize it).
1178 */
1179 private void readObject(java.io.ObjectInputStream s)
1180 throws IOException, ClassNotFoundException {
1181
1182 // Read in the threshold, loadfactor, and any hidden stuff
1183 s.defaultReadObject();
1184
1185 int cap = s.readInt();
1186 table = newTable(cap);
1187 for (int i = 0; i < segments.length; ++i)
1188 segments[i] = new Segment();
1189
1190
1191 // Read the keys and values, and put the mappings in the table
1192 while (true) {
1193 K key = (K) s.readObject();
1194 V value = (V) s.readObject();
1195 if (key == null)
1196 break;
1197 put(key, value);
1198 }
1199 }
1200 }