ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
Revision: 1.2
Committed: Tue May 27 18:14:39 2003 UTC (21 years ago) by dl
Branch: MAIN
Changes since 1.1: +103 -45 lines
Log Message:
re-check-in initial implementations

File Contents

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