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