1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.commons.collections4.map;
23
24
25
26
27
28
29
30 import java.lang.ref.Reference;
31 import java.lang.ref.ReferenceQueue;
32 import java.lang.ref.SoftReference;
33 import java.lang.ref.WeakReference;
34 import java.util.AbstractCollection;
35 import java.util.AbstractMap;
36 import java.util.AbstractSet;
37 import java.util.Arrays;
38 import java.util.Collection;
39 import java.util.ConcurrentModificationException;
40 import java.util.EnumSet;
41 import java.util.Enumeration;
42 import java.util.HashMap;
43 import java.util.Hashtable;
44 import java.util.IdentityHashMap;
45 import java.util.Iterator;
46 import java.util.Map;
47 import java.util.NoSuchElementException;
48 import java.util.Objects;
49 import java.util.Set;
50 import java.util.concurrent.ConcurrentMap;
51 import java.util.concurrent.locks.ReentrantLock;
52 import java.util.function.BiFunction;
53 import java.util.function.Function;
54 import java.util.function.Supplier;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public static class Builder<K, V> implements Supplier<ConcurrentReferenceHashMap<K, V>> {
146
147 private static final Map<?, ?> DEFAULT_SOURCE_MAP = null;
148
149 private int initialCapacity = DEFAULT_INITIAL_CAPACITY;
150 private float loadFactor = DEFAULT_LOAD_FACTOR;
151 private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL;
152 private ReferenceType keyReferenceType = DEFAULT_KEY_TYPE;
153 private ReferenceType valueReferenceType = DEFAULT_VALUE_TYPE;
154 private EnumSet<Option> options = DEFAULT_OPTIONS;
155 @SuppressWarnings("unchecked")
156 private Map<? extends K, ? extends V> sourceMap = (Map<? extends K, ? extends V>) DEFAULT_SOURCE_MAP;
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 @Override
177 public ConcurrentReferenceHashMap<K, V> get() {
178 final ConcurrentReferenceHashMap<K, V> map = new ConcurrentReferenceHashMap<>(initialCapacity, loadFactor, concurrencyLevel, keyReferenceType,
179 valueReferenceType, options);
180 if (sourceMap != null) {
181 map.putAll(sourceMap);
182 }
183 return map;
184 }
185
186
187
188
189
190
191
192 public Builder<K, V> setConcurrencyLevel(final int concurrencyLevel) {
193 this.concurrencyLevel = concurrencyLevel;
194 return this;
195 }
196
197
198
199
200
201
202
203 public Builder<K, V> setInitialCapacity(final int initialCapacity) {
204 this.initialCapacity = initialCapacity;
205 return this;
206 }
207
208
209
210
211
212
213
214 public Builder<K, V> setKeyReferenceType(final ReferenceType keyReferenceType) {
215 this.keyReferenceType = keyReferenceType;
216 return this;
217 }
218
219
220
221
222
223
224
225 public Builder<K, V> setLoadFactor(final float loadFactor) {
226 this.loadFactor = loadFactor;
227 return this;
228 }
229
230
231
232
233
234
235
236 public Builder<K, V> setOptions(final EnumSet<Option> options) {
237 this.options = options;
238 return this;
239 }
240
241
242
243
244
245
246
247 public Builder<K, V> setSourceMap(final Map<? extends K, ? extends V> sourceMap) {
248 this.sourceMap = sourceMap;
249 return this;
250 }
251
252
253
254
255
256
257
258 public Builder<K, V> setValueReferenceType(final ReferenceType valueReferenceType) {
259 this.valueReferenceType = valueReferenceType;
260 return this;
261 }
262
263
264
265
266
267
268 public Builder<K, V> softKeys() {
269 setKeyReferenceType(ReferenceType.SOFT);
270 return this;
271 }
272
273
274
275
276
277
278 public Builder<K, V> softValues() {
279 setValueReferenceType(ReferenceType.SOFT);
280 return this;
281 }
282
283
284
285
286
287
288 public Builder<K, V> strongKeys() {
289 setKeyReferenceType(ReferenceType.STRONG);
290 return this;
291 }
292
293
294
295
296
297
298 public Builder<K, V> strongValues() {
299 setValueReferenceType(ReferenceType.STRONG);
300 return this;
301 }
302
303
304
305
306
307
308 public Builder<K, V> weakKeys() {
309 setKeyReferenceType(ReferenceType.WEAK);
310 return this;
311 }
312
313
314
315
316
317
318 public Builder<K, V> weakValues() {
319 setValueReferenceType(ReferenceType.WEAK);
320 return this;
321 }
322
323 }
324
325
326
327
328 private final class CachedEntryIterator extends HashIterator implements Iterator<Entry<K, V>> {
329 private final InitializableEntry<K, V> entry = new InitializableEntry<>();
330
331 @Override
332 public Entry<K, V> next() {
333 final HashEntry<K, V> e = super.nextEntry();
334 return entry.init(e.key(), e.value());
335 }
336 }
337
338 private final class EntryIterator extends HashIterator implements Iterator<Entry<K, V>> {
339 @Override
340 public Entry<K, V> next() {
341 final HashEntry<K, V> e = super.nextEntry();
342 return new WriteThroughEntry(e.key(), e.value());
343 }
344 }
345
346 private final class EntrySet extends AbstractSet<Entry<K, V>> {
347
348 private final boolean cached;
349
350 private EntrySet(final boolean cached) {
351 this.cached = cached;
352 }
353
354 @Override
355 public void clear() {
356 ConcurrentReferenceHashMap.this.clear();
357 }
358
359 @Override
360 public boolean contains(final Object o) {
361 if (!(o instanceof Map.Entry)) {
362 return false;
363 }
364 final V v = ConcurrentReferenceHashMap.this.get(((Entry<?, ?>) o).getKey());
365 return Objects.equals(v, ((Entry<?, ?>) o).getValue());
366 }
367
368 @Override
369 public boolean isEmpty() {
370 return ConcurrentReferenceHashMap.this.isEmpty();
371 }
372
373 @Override
374 public Iterator<Entry<K, V>> iterator() {
375 return cached ? new CachedEntryIterator() : new EntryIterator();
376 }
377
378 @Override
379 public boolean remove(final Object o) {
380 if (!(o instanceof Map.Entry)) {
381 return false;
382 }
383 final Entry<?, ?> e = (Entry<?, ?>) o;
384 return ConcurrentReferenceHashMap.this.remove(e.getKey(), e.getValue());
385 }
386
387 @Override
388 public int size() {
389 return ConcurrentReferenceHashMap.this.size();
390 }
391 }
392
393
394
395
396
397
398
399
400
401 private static final class HashEntry<K, V> {
402
403 @SuppressWarnings("unchecked")
404 static <K, V> HashEntry<K, V>[] newArray(final int i) {
405 return new HashEntry[i];
406 }
407
408 private final Object keyRef;
409 private final int hash;
410 private volatile Object valueRef;
411 private final HashEntry<K, V> next;
412
413 HashEntry(final K key, final int hash, final HashEntry<K, V> next, final V value, final ReferenceType keyType, final ReferenceType valueType,
414 final ReferenceQueue<Object> refQueue) {
415 this.hash = hash;
416 this.next = next;
417 this.keyRef = newKeyReference(key, keyType, refQueue);
418 this.valueRef = newValueReference(value, valueType, refQueue);
419 }
420
421 @SuppressWarnings("unchecked")
422 V dereferenceValue(final Object value) {
423 if (value instanceof KeyReference) {
424 return ((Reference<V>) value).get();
425 }
426 return (V) value;
427 }
428
429 @SuppressWarnings("unchecked")
430 K key() {
431 if (keyRef instanceof KeyReference) {
432 return ((Reference<K>) keyRef).get();
433 }
434 return (K) keyRef;
435 }
436
437 Object newKeyReference(final K key, final ReferenceType keyType, final ReferenceQueue<Object> refQueue) {
438 if (keyType == ReferenceType.WEAK) {
439 return new WeakKeyReference<>(key, hash, refQueue);
440 }
441 if (keyType == ReferenceType.SOFT) {
442 return new SoftKeyReference<>(key, hash, refQueue);
443 }
444
445 return key;
446 }
447
448 Object newValueReference(final V value, final ReferenceType valueType, final ReferenceQueue<Object> refQueue) {
449 if (valueType == ReferenceType.WEAK) {
450 return new WeakValueReference<>(value, keyRef, hash, refQueue);
451 }
452 if (valueType == ReferenceType.SOFT) {
453 return new SoftValueReference<>(value, keyRef, hash, refQueue);
454 }
455
456 return value;
457 }
458
459 void setValue(final V value, final ReferenceType valueType, final ReferenceQueue<Object> refQueue) {
460 this.valueRef = newValueReference(value, valueType, refQueue);
461 }
462
463 V value() {
464 return dereferenceValue(valueRef);
465 }
466 }
467
468 private abstract class HashIterator {
469 private int nextSegmentIndex;
470 private int nextTableIndex;
471 private HashEntry<K, V>[] currentTable;
472 private HashEntry<K, V> nextEntry;
473 private HashEntry<K, V> lastReturned;
474
475 private K currentKey;
476
477 private HashIterator() {
478 nextSegmentIndex = segments.length - 1;
479 nextTableIndex = -1;
480 advance();
481 }
482
483 final void advance() {
484 if (nextEntry != null && (nextEntry = nextEntry.next) != null) {
485 return;
486 }
487 while (nextTableIndex >= 0) {
488 if ((nextEntry = currentTable[nextTableIndex--]) != null) {
489 return;
490 }
491 }
492 while (nextSegmentIndex >= 0) {
493 final Segment<K, V> seg = segments[nextSegmentIndex--];
494 if (seg.count != 0) {
495 currentTable = seg.table;
496 for (int j = currentTable.length - 1; j >= 0; --j) {
497 if ((nextEntry = currentTable[j]) != null) {
498 nextTableIndex = j - 1;
499 return;
500 }
501 }
502 }
503 }
504 }
505
506 public boolean hasMoreElements() {
507 return hasNext();
508 }
509
510 public boolean hasNext() {
511 while (nextEntry != null) {
512 if (nextEntry.key() != null) {
513 return true;
514 }
515 advance();
516 }
517 return false;
518 }
519
520 HashEntry<K, V> nextEntry() {
521 do {
522 if (nextEntry == null) {
523 throw new NoSuchElementException();
524 }
525 lastReturned = nextEntry;
526 currentKey = lastReturned.key();
527 advance();
528 } while (currentKey == null);
529 return lastReturned;
530 }
531
532 public void remove() {
533 if (lastReturned == null) {
534 throw new IllegalStateException();
535 }
536 ConcurrentReferenceHashMap.this.remove(currentKey);
537 lastReturned = null;
538 }
539 }
540
541 private static final class InitializableEntry<K, V> implements Entry<K, V> {
542 private K key;
543 private V value;
544
545 @Override
546 public K getKey() {
547 return key;
548 }
549
550 @Override
551 public V getValue() {
552 return value;
553 }
554
555 public Entry<K, V> init(final K key, final V value) {
556 this.key = key;
557 this.value = value;
558 return this;
559 }
560
561 @Override
562 public V setValue(final V value) {
563 throw new UnsupportedOperationException();
564 }
565 }
566
567 private final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> {
568 @Override
569 public K next() {
570 return super.nextEntry().key();
571 }
572
573 @Override
574 public K nextElement() {
575 return super.nextEntry().key();
576 }
577 }
578
579 private interface KeyReference {
580 int keyHash();
581
582 Object keyRef();
583 }
584
585 private final class KeySet extends AbstractSet<K> {
586 @Override
587 public void clear() {
588 ConcurrentReferenceHashMap.this.clear();
589 }
590
591 @Override
592 public boolean contains(final Object o) {
593 return ConcurrentReferenceHashMap.this.containsKey(o);
594 }
595
596 @Override
597 public boolean isEmpty() {
598 return ConcurrentReferenceHashMap.this.isEmpty();
599 }
600
601 @Override
602 public Iterator<K> iterator() {
603 return new KeyIterator();
604 }
605
606 @Override
607 public boolean remove(final Object o) {
608 return ConcurrentReferenceHashMap.this.remove(o) != null;
609 }
610
611 @Override
612 public int size() {
613 return ConcurrentReferenceHashMap.this.size();
614 }
615 }
616
617
618
619
620 public enum Option {
621
622
623
624
625 IDENTITY_COMPARISONS
626 }
627
628
629
630
631 public enum ReferenceType {
632
633
634
635 STRONG,
636
637
638
639 WEAK,
640
641
642
643 SOFT
644 }
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674 private static final class Segment<K, V> extends ReentrantLock {
675
676 private static final long serialVersionUID = 1L;
677
678 @SuppressWarnings("unchecked")
679 static <K, V> Segment<K, V>[] newArray(final int i) {
680 return new Segment[i];
681 }
682
683
684
685
686
687
688 private transient volatile int count;
689
690
691
692
693
694
695
696
697 private transient int modCount;
698
699
700
701
702
703 private transient int threshold;
704
705
706
707
708 private transient volatile HashEntry<K, V>[] table;
709
710
711
712
713 private final float loadFactor;
714
715
716
717
718 private transient volatile ReferenceQueue<Object> refQueue;
719
720 private final ReferenceType keyType;
721
722 private final ReferenceType valueType;
723
724 private final boolean identityComparisons;
725
726 Segment(final int initialCapacity, final float loadFactor, final ReferenceType keyType, final ReferenceType valueType,
727 final boolean identityComparisons) {
728 this.loadFactor = loadFactor;
729 this.keyType = keyType;
730 this.valueType = valueType;
731 this.identityComparisons = identityComparisons;
732 setTable(HashEntry.<K, V>newArray(initialCapacity));
733 }
734
735 V apply(final K key, final int hash, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
736 lock();
737 try {
738 final V oldValue = get(key, hash);
739 final V newValue = remappingFunction.apply(key, oldValue);
740
741 if (newValue == null) {
742
743 if (oldValue != null) {
744
745 removeInternal(key, hash, oldValue, false);
746 }
747 return null;
748 }
749
750 putInternal(key, hash, newValue, null, false);
751 return newValue;
752 } finally {
753 unlock();
754 }
755 }
756
757 V applyIfPresent(final K key, final int hash, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
758 lock();
759 try {
760 final V oldValue = get(key, hash);
761 if (oldValue == null) {
762 return null;
763 }
764
765 final V newValue = remappingFunction.apply(key, oldValue);
766
767 if (newValue == null) {
768 removeInternal(key, hash, oldValue, false);
769 return null;
770 }
771 putInternal(key, hash, newValue, null, false);
772 return newValue;
773 } finally {
774 unlock();
775 }
776 }
777
778 void clear() {
779 if (count != 0) {
780 lock();
781 try {
782 final HashEntry<K, V>[] tab = table;
783 Arrays.fill(tab, null);
784 ++modCount;
785
786 refQueue = new ReferenceQueue<>();
787
788 count = 0;
789 } finally {
790 unlock();
791 }
792 }
793 }
794
795 boolean containsKey(final Object key, final int hash) {
796
797 if (count != 0) {
798 HashEntry<K, V> e = getFirst(hash);
799 while (e != null) {
800 if (e.hash == hash && keyEq(key, e.key())) {
801 return true;
802 }
803 e = e.next;
804 }
805 }
806 return false;
807 }
808
809 boolean containsValue(final Object value) {
810
811 if (count != 0) {
812 final HashEntry<K, V>[] tab = table;
813 final int len = tab.length;
814 for (int i = 0; i < len; i++) {
815 for (HashEntry<K, V> e = tab[i]; e != null; e = e.next) {
816 final Object opaque = e.valueRef;
817 V v;
818 if (opaque == null) {
819
820 v = readValueUnderLock(e);
821 } else {
822 v = e.dereferenceValue(opaque);
823 }
824 if (Objects.equals(value, v)) {
825 return true;
826 }
827 }
828 }
829 }
830 return false;
831 }
832
833
834 V get(final Object key, final int hash) {
835
836 if (count != 0) {
837 HashEntry<K, V> e = getFirst(hash);
838 while (e != null) {
839 if (e.hash == hash && keyEq(key, e.key())) {
840 final Object opaque = e.valueRef;
841 if (opaque != null) {
842 return e.dereferenceValue(opaque);
843 }
844
845 return readValueUnderLock(e);
846 }
847 e = e.next;
848 }
849 }
850 return null;
851 }
852
853
854
855
856 HashEntry<K, V> getFirst(final int hash) {
857 final HashEntry<K, V>[] tab = table;
858 return tab[hash & tab.length - 1];
859 }
860
861 V getValue(final K key, final V value, final Function<? super K, ? extends V> function) {
862 return value != null ? value : function.apply(key);
863 }
864
865 private boolean keyEq(final Object src, final Object dest) {
866 return identityComparisons ? src == dest : Objects.equals(src, dest);
867 }
868
869 HashEntry<K, V> newHashEntry(final K key, final int hash, final HashEntry<K, V> next, final V value) {
870 return new HashEntry<>(key, hash, next, value, keyType, valueType, refQueue);
871 }
872
873
874
875
876 V put(final K key, final int hash, final V value, final Function<? super K, ? extends V> function, final boolean onlyIfAbsent) {
877 lock();
878 try {
879 return putInternal(key, hash, value, function, onlyIfAbsent);
880 } finally {
881 unlock();
882 }
883 }
884
885 private V putInternal(final K key, final int hash, final V value, final Function<? super K, ? extends V> function, final boolean onlyIfAbsent) {
886 removeStale();
887 int c = count;
888
889 if (c++ > threshold) {
890 final int reduced = rehash();
891
892 if (reduced > 0) {
893
894 count = (c -= reduced) - 1;
895 }
896 }
897 final HashEntry<K, V>[] tab = table;
898 final int index = hash & tab.length - 1;
899 final HashEntry<K, V> first = tab[index];
900 HashEntry<K, V> e = first;
901 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
902 e = e.next;
903 }
904 V resultValue;
905 if (e != null) {
906 resultValue = e.value();
907 if (!onlyIfAbsent) {
908 e.setValue(getValue(key, value, function), valueType, refQueue);
909 }
910 } else {
911 final V v = getValue(key, value, function);
912 resultValue = function != null ? v : null;
913
914 if (v != null) {
915 ++modCount;
916 tab[index] = newHashEntry(key, hash, first, v);
917
918 count = c;
919 }
920 }
921 return resultValue;
922 }
923
924
925
926
927
928 V readValueUnderLock(final HashEntry<K, V> e) {
929 lock();
930 try {
931 removeStale();
932 return e.value();
933 } finally {
934 unlock();
935 }
936 }
937
938 int rehash() {
939 final HashEntry<K, V>[] oldTable = table;
940 final int oldCapacity = oldTable.length;
941 if (oldCapacity >= MAXIMUM_CAPACITY) {
942 return 0;
943 }
944
945
946
947
948
949
950
951 final HashEntry<K, V>[] newTable = HashEntry.newArray(oldCapacity << 1);
952 threshold = (int) (newTable.length * loadFactor);
953 final int sizeMask = newTable.length - 1;
954 int reduce = 0;
955 for (int i = 0; i < oldCapacity; i++) {
956
957
958 final HashEntry<K, V> e = oldTable[i];
959 if (e != null) {
960 final HashEntry<K, V> next = e.next;
961 final int idx = e.hash & sizeMask;
962
963 if (next == null) {
964 newTable[idx] = e;
965 } else {
966
967 HashEntry<K, V> lastRun = e;
968 int lastIdx = idx;
969 for (HashEntry<K, V> last = next; last != null; last = last.next) {
970 final int k = last.hash & sizeMask;
971 if (k != lastIdx) {
972 lastIdx = k;
973 lastRun = last;
974 }
975 }
976 newTable[lastIdx] = lastRun;
977
978 for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
979
980 final K key = p.key();
981 if (key == null) {
982 reduce++;
983 continue;
984 }
985 final int k = p.hash & sizeMask;
986 final HashEntry<K, V> n = newTable[k];
987 newTable[k] = newHashEntry(key, p.hash, n, p.value());
988 }
989 }
990 }
991 }
992 table = newTable;
993 return reduce;
994 }
995
996
997
998
999 V remove(final Object key, final int hash, final Object value, final boolean refRemove) {
1000 lock();
1001 try {
1002 return removeInternal(key, hash, value, refRemove);
1003 } finally {
1004 unlock();
1005 }
1006 }
1007
1008 private V removeInternal(final Object key, final int hash, final Object value, final boolean refRemove) {
1009 if (!refRemove) {
1010 removeStale();
1011 }
1012 int c = count - 1;
1013 final HashEntry<K, V>[] tab = table;
1014 final int index = hash & tab.length - 1;
1015 final HashEntry<K, V> first = tab[index];
1016 HashEntry<K, V> e = first;
1017
1018 while (e != null && key != e.keyRef && (refRemove || hash != e.hash || !keyEq(key, e.key()))) {
1019 e = e.next;
1020 }
1021
1022 V oldValue = null;
1023 if (e != null) {
1024 final V v = e.value();
1025 if (value == null || value.equals(v)) {
1026 oldValue = v;
1027
1028
1029
1030 ++modCount;
1031 HashEntry<K, V> newFirst = e.next;
1032 for (HashEntry<K, V> p = first; p != e; p = p.next) {
1033 final K pKey = p.key();
1034
1035 if (pKey == null) {
1036 c--;
1037 continue;
1038 }
1039 newFirst = newHashEntry(pKey, p.hash, newFirst, p.value());
1040 }
1041 tab[index] = newFirst;
1042
1043 count = c;
1044 }
1045 }
1046 return oldValue;
1047 }
1048
1049 void removeStale() {
1050 KeyReference ref;
1051 while ((ref = (KeyReference) refQueue.poll()) != null) {
1052 remove(ref.keyRef(), ref.keyHash(), null, true);
1053 }
1054 }
1055
1056 V replace(final K key, final int hash, final V newValue) {
1057 lock();
1058 try {
1059 return replaceInternal(key, hash, newValue);
1060 } finally {
1061 unlock();
1062 }
1063 }
1064
1065 boolean replace(final K key, final int hash, final V oldValue, final V newValue) {
1066 lock();
1067 try {
1068 return replaceInternal2(key, hash, oldValue, newValue);
1069 } finally {
1070 unlock();
1071 }
1072 }
1073
1074 private V replaceInternal(final K key, final int hash, final V newValue) {
1075 removeStale();
1076 HashEntry<K, V> e = getFirst(hash);
1077 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
1078 e = e.next;
1079 }
1080 V oldValue = null;
1081 if (e != null) {
1082 oldValue = e.value();
1083 e.setValue(newValue, valueType, refQueue);
1084 }
1085 return oldValue;
1086 }
1087
1088 private boolean replaceInternal2(final K key, final int hash, final V oldValue, final V newValue) {
1089 removeStale();
1090 HashEntry<K, V> e = getFirst(hash);
1091 while (e != null && (e.hash != hash || !keyEq(key, e.key()))) {
1092 e = e.next;
1093 }
1094 boolean replaced = false;
1095 if (e != null && Objects.equals(oldValue, e.value())) {
1096 replaced = true;
1097 e.setValue(newValue, valueType, refQueue);
1098 }
1099 return replaced;
1100 }
1101
1102
1103
1104
1105 void setTable(final HashEntry<K, V>[] newTable) {
1106 threshold = (int) (newTable.length * loadFactor);
1107 table = newTable;
1108 refQueue = new ReferenceQueue<>();
1109 }
1110 }
1111
1112 private static class SimpleEntry<K, V> implements Entry<K, V> {
1113
1114 private static boolean eq(final Object o1, final Object o2) {
1115 return Objects.equals(o1, o2);
1116 }
1117
1118 private final K key;
1119
1120 private V value;
1121
1122 SimpleEntry(final K key, final V value) {
1123 this.key = key;
1124 this.value = value;
1125 }
1126
1127 @Override
1128 public boolean equals(final Object o) {
1129 if (!(o instanceof Map.Entry)) {
1130 return false;
1131 }
1132 final Entry<?, ?> e = (Entry<?, ?>) o;
1133 return eq(key, e.getKey()) && eq(value, e.getValue());
1134 }
1135
1136 @Override
1137 public K getKey() {
1138 return key;
1139 }
1140
1141 @Override
1142 public V getValue() {
1143 return value;
1144 }
1145
1146 @Override
1147 public int hashCode() {
1148 return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
1149 }
1150
1151 @Override
1152 public V setValue(final V value) {
1153 final V oldValue = this.value;
1154 this.value = value;
1155 return oldValue;
1156 }
1157
1158 @Override
1159 public String toString() {
1160 return key + "=" + value;
1161 }
1162 }
1163
1164
1165
1166
1167 private static final class SoftKeyReference<K> extends SoftReference<K> implements KeyReference {
1168
1169 private final int hash;
1170
1171 SoftKeyReference(final K key, final int hash, final ReferenceQueue<Object> refQueue) {
1172 super(key, refQueue);
1173 this.hash = hash;
1174 }
1175
1176 @Override
1177 public int keyHash() {
1178 return hash;
1179 }
1180
1181 @Override
1182 public Object keyRef() {
1183 return this;
1184 }
1185 }
1186
1187 private static final class SoftValueReference<V> extends SoftReference<V> implements KeyReference {
1188 private final Object keyRef;
1189 private final int hash;
1190
1191 SoftValueReference(final V value, final Object keyRef, final int hash, final ReferenceQueue<Object> refQueue) {
1192 super(value, refQueue);
1193 this.keyRef = keyRef;
1194 this.hash = hash;
1195 }
1196
1197 @Override
1198 public int keyHash() {
1199 return hash;
1200 }
1201
1202 @Override
1203 public Object keyRef() {
1204 return keyRef;
1205 }
1206 }
1207
1208 private final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> {
1209 @Override
1210 public V next() {
1211 return super.nextEntry().value();
1212 }
1213
1214 @Override
1215 public V nextElement() {
1216 return super.nextEntry().value();
1217 }
1218 }
1219
1220 private final class Values extends AbstractCollection<V> {
1221 @Override
1222 public void clear() {
1223 ConcurrentReferenceHashMap.this.clear();
1224 }
1225
1226 @Override
1227 public boolean contains(final Object o) {
1228 return ConcurrentReferenceHashMap.this.containsValue(o);
1229 }
1230
1231 @Override
1232 public boolean isEmpty() {
1233 return ConcurrentReferenceHashMap.this.isEmpty();
1234 }
1235
1236 @Override
1237 public Iterator<V> iterator() {
1238 return new ValueIterator();
1239 }
1240
1241 @Override
1242 public int size() {
1243 return ConcurrentReferenceHashMap.this.size();
1244 }
1245 }
1246
1247
1248
1249
1250 private static final class WeakKeyReference<K> extends WeakReference<K> implements KeyReference {
1251 private final int hash;
1252
1253 WeakKeyReference(final K key, final int hash, final ReferenceQueue<Object> refQueue) {
1254 super(key, refQueue);
1255 this.hash = hash;
1256 }
1257
1258 @Override
1259 public int keyHash() {
1260 return hash;
1261 }
1262
1263 @Override
1264 public Object keyRef() {
1265 return this;
1266 }
1267 }
1268
1269 private static final class WeakValueReference<V> extends WeakReference<V> implements KeyReference {
1270 private final Object keyRef;
1271 private final int hash;
1272
1273 WeakValueReference(final V value, final Object keyRef, final int hash, final ReferenceQueue<Object> refQueue) {
1274 super(value, refQueue);
1275 this.keyRef = keyRef;
1276 this.hash = hash;
1277 }
1278
1279 @Override
1280 public int keyHash() {
1281 return hash;
1282 }
1283
1284 @Override
1285 public Object keyRef() {
1286 return keyRef;
1287 }
1288 }
1289
1290
1291
1292
1293 private final class WriteThroughEntry extends SimpleEntry<K, V> {
1294
1295 private WriteThroughEntry(final K k, final V v) {
1296 super(k, v);
1297 }
1298
1299
1300
1301
1302
1303
1304 @Override
1305 public V setValue(final V value) {
1306 if (value == null) {
1307 throw new NullPointerException();
1308 }
1309 final V v = super.setValue(value);
1310 ConcurrentReferenceHashMap.this.put(getKey(), value);
1311 return v;
1312 }
1313 }
1314
1315 static final ReferenceType DEFAULT_KEY_TYPE = ReferenceType.WEAK;
1316
1317 static final ReferenceType DEFAULT_VALUE_TYPE = ReferenceType.STRONG;
1318
1319 static final EnumSet<Option> DEFAULT_OPTIONS = null;
1320
1321
1322
1323
1324 static final int DEFAULT_INITIAL_CAPACITY = 16;
1325
1326
1327
1328
1329 static final float DEFAULT_LOAD_FACTOR = 0.75f;
1330
1331
1332
1333
1334 static final int DEFAULT_CONCURRENCY_LEVEL = 16;
1335
1336
1337
1338
1339
1340 private static final int MAXIMUM_CAPACITY = 1 << 30;
1341
1342
1343
1344
1345 private static final int MAX_SEGMENTS = 1 << 16;
1346
1347
1348
1349
1350
1351 private static final int RETRIES_BEFORE_LOCK = 2;
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375 public static <K, V> Builder<K, V> builder() {
1376 return new Builder<>();
1377 }
1378
1379
1380
1381
1382
1383
1384 private static int hash(int h) {
1385
1386
1387 h += h << 15 ^ 0xffffcd7d;
1388 h ^= h >>> 10;
1389 h += h << 3;
1390 h ^= h >>> 6;
1391 h += (h << 2) + (h << 14);
1392 return h ^ h >>> 16;
1393 }
1394
1395
1396
1397
1398 private final int segmentMask;
1399
1400
1401
1402
1403 private final int segmentShift;
1404
1405
1406
1407
1408 private final Segment<K, V>[] segments;
1409
1410 private final boolean identityComparisons;
1411
1412 private transient Set<K> keySet;
1413
1414 private transient Set<Entry<K, V>> entrySet;
1415
1416 private transient Collection<V> values;
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434 private ConcurrentReferenceHashMap(int initialCapacity, final float loadFactor, int concurrencyLevel, final ReferenceType keyType,
1435 final ReferenceType valueType, final EnumSet<Option> options) {
1436 if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0) {
1437 throw new IllegalArgumentException();
1438 }
1439 if (concurrencyLevel > MAX_SEGMENTS) {
1440 concurrencyLevel = MAX_SEGMENTS;
1441 }
1442
1443 int sshift = 0;
1444 int ssize = 1;
1445 while (ssize < concurrencyLevel) {
1446 ++sshift;
1447 ssize <<= 1;
1448 }
1449 segmentShift = 32 - sshift;
1450 segmentMask = ssize - 1;
1451 this.segments = Segment.newArray(ssize);
1452 if (initialCapacity > MAXIMUM_CAPACITY) {
1453 initialCapacity = MAXIMUM_CAPACITY;
1454 }
1455 int c = initialCapacity / ssize;
1456 if (c * ssize < initialCapacity) {
1457 ++c;
1458 }
1459 int cap = 1;
1460 while (cap < c) {
1461 cap <<= 1;
1462 }
1463 identityComparisons = options != null && options.contains(Option.IDENTITY_COMPARISONS);
1464 for (int i = 0; i < this.segments.length; ++i) {
1465 this.segments[i] = new Segment<>(cap, loadFactor, keyType, valueType, identityComparisons);
1466 }
1467 }
1468
1469
1470
1471
1472 @Override
1473 public void clear() {
1474 for (final Segment<K, V> segment : segments) {
1475 segment.clear();
1476 }
1477 }
1478
1479 @Override
1480 public V compute(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1481 Objects.requireNonNull(key);
1482 Objects.requireNonNull(remappingFunction);
1483
1484 final int hash = hashOf(key);
1485 final Segment<K, V> segment = segmentFor(hash);
1486 return segment.apply(key, hash, remappingFunction);
1487 }
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507 @Override
1508 public V computeIfAbsent(final K key, final Function<? super K, ? extends V> mappingFunction) {
1509 Objects.requireNonNull(key);
1510 Objects.requireNonNull(mappingFunction);
1511
1512 final int hash = hashOf(key);
1513 final Segment<K, V> segment = segmentFor(hash);
1514 final V v = segment.get(key, hash);
1515 return v == null ? segment.put(key, hash, null, mappingFunction, true) : v;
1516 }
1517
1518 @Override
1519 public V computeIfPresent(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1520 Objects.requireNonNull(key);
1521 Objects.requireNonNull(remappingFunction);
1522
1523 final int hash = hashOf(key);
1524 final Segment<K, V> segment = segmentFor(hash);
1525 final V v = segment.get(key, hash);
1526 if (v == null) {
1527 return null;
1528 }
1529
1530 return segmentFor(hash).applyIfPresent(key, hash, remappingFunction);
1531 }
1532
1533
1534
1535
1536
1537
1538
1539
1540 @Override
1541 public boolean containsKey(final Object key) {
1542 final int hash = hashOf(key);
1543 return segmentFor(hash).containsKey(key, hash);
1544 }
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554 @Override
1555 public boolean containsValue(final Object value) {
1556 if (value == null) {
1557 throw new NullPointerException();
1558 }
1559
1560 final Segment<K, V>[] segments = this.segments;
1561 final int[] mc = new int[segments.length];
1562
1563 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
1564
1565 int mcsum = 0;
1566 for (int i = 0; i < segments.length; ++i) {
1567
1568 mcsum += mc[i] = segments[i].modCount;
1569 if (segments[i].containsValue(value)) {
1570 return true;
1571 }
1572 }
1573 boolean cleanSweep = true;
1574 if (mcsum != 0) {
1575 for (int i = 0; i < segments.length; ++i) {
1576
1577 if (mc[i] != segments[i].modCount) {
1578 cleanSweep = false;
1579 break;
1580 }
1581 }
1582 }
1583 if (cleanSweep) {
1584 return false;
1585 }
1586 }
1587
1588 for (final Segment<K, V> segment : segments) {
1589 segment.lock();
1590 }
1591 boolean found = false;
1592 try {
1593 for (final Segment<K, V> segment : segments) {
1594 if (segment.containsValue(value)) {
1595 found = true;
1596 break;
1597 }
1598 }
1599 } finally {
1600 for (final Segment<K, V> segment : segments) {
1601 segment.unlock();
1602 }
1603 }
1604 return found;
1605 }
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617 @Override
1618 public Set<Entry<K, V>> entrySet() {
1619 final Set<Entry<K, V>> es = entrySet;
1620 return es != null ? es : (entrySet = new EntrySet(false));
1621 }
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 @Override
1633 public V get(final Object key) {
1634 final int hash = hashOf(key);
1635 return segmentFor(hash).get(key, hash);
1636 }
1637
1638 private int hashOf(final Object key) {
1639 return hash(identityComparisons ? System.identityHashCode(key) : key.hashCode());
1640 }
1641
1642
1643
1644
1645
1646
1647 @Override
1648 public boolean isEmpty() {
1649 final Segment<K, V>[] segments = this.segments;
1650
1651
1652
1653
1654
1655 final int[] mc = new int[segments.length];
1656 int mcsum = 0;
1657 for (int i = 0; i < segments.length; ++i) {
1658 if (segments[i].count != 0) {
1659 return false;
1660 }
1661 mcsum += mc[i] = segments[i].modCount;
1662 }
1663
1664
1665
1666 if (mcsum != 0) {
1667 for (int i = 0; i < segments.length; ++i) {
1668 if (segments[i].count != 0 || mc[i] != segments[i].modCount) {
1669 return false;
1670 }
1671 }
1672 }
1673 return true;
1674 }
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685 @Override
1686 public Set<K> keySet() {
1687 final Set<K> ks = keySet;
1688 return ks != null ? ks : (keySet = new KeySet());
1689 }
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699 public void purgeStaleEntries() {
1700 for (final Segment<K, V> segment : segments) {
1701 segment.removeStale();
1702 }
1703 }
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716 @Override
1717 public V put(final K key, final V value) {
1718 if (key == null || value == null) {
1719 throw new NullPointerException();
1720 }
1721 final int hash = hashOf(key);
1722 return segmentFor(hash).put(key, hash, value, null, false);
1723 }
1724
1725
1726
1727
1728
1729
1730
1731 @Override
1732 public void putAll(final Map<? extends K, ? extends V> m) {
1733 for (final Entry<? extends K, ? extends V> e : m.entrySet()) {
1734 put(e.getKey(), e.getValue());
1735 }
1736 }
1737
1738
1739
1740
1741
1742
1743
1744 @Override
1745 public V putIfAbsent(final K key, final V value) {
1746 if (value == null) {
1747 throw new NullPointerException();
1748 }
1749 final int hash = hashOf(key);
1750 return segmentFor(hash).put(key, hash, value, null, true);
1751 }
1752
1753
1754
1755
1756
1757
1758
1759
1760 @Override
1761 public V remove(final Object key) {
1762 final int hash = hashOf(key);
1763 return segmentFor(hash).remove(key, hash, null, false);
1764 }
1765
1766
1767
1768
1769
1770
1771 @Override
1772 public boolean remove(final Object key, final Object value) {
1773 final int hash = hashOf(key);
1774 if (value == null) {
1775 return false;
1776 }
1777 return segmentFor(hash).remove(key, hash, value, false) != null;
1778 }
1779
1780
1781
1782
1783
1784
1785
1786 @Override
1787 public V replace(final K key, final V value) {
1788 if (value == null) {
1789 throw new NullPointerException();
1790 }
1791 final int hash = hashOf(key);
1792 return segmentFor(hash).replace(key, hash, value);
1793 }
1794
1795
1796
1797
1798
1799
1800 @Override
1801 public boolean replace(final K key, final V oldValue, final V newValue) {
1802 if (oldValue == null || newValue == null) {
1803 throw new NullPointerException();
1804 }
1805 final int hash = hashOf(key);
1806 return segmentFor(hash).replace(key, hash, oldValue, newValue);
1807 }
1808
1809
1810
1811
1812
1813
1814
1815 private Segment<K, V> segmentFor(final int hash) {
1816 return segments[hash >>> segmentShift & segmentMask];
1817 }
1818
1819
1820
1821
1822
1823
1824
1825 @Override
1826 public int size() {
1827 final Segment<K, V>[] segments = this.segments;
1828 long sum = 0;
1829 long check = 0;
1830 final int[] mc = new int[segments.length];
1831
1832
1833 for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
1834 check = 0;
1835 sum = 0;
1836 int mcsum = 0;
1837 for (int i = 0; i < segments.length; ++i) {
1838 sum += segments[i].count;
1839 mcsum += mc[i] = segments[i].modCount;
1840 }
1841 if (mcsum != 0) {
1842 for (int i = 0; i < segments.length; ++i) {
1843 check += segments[i].count;
1844 if (mc[i] != segments[i].modCount) {
1845
1846 check = -1;
1847 break;
1848 }
1849 }
1850 }
1851 if (check == sum) {
1852 break;
1853 }
1854 }
1855 if (check != sum) {
1856
1857 sum = 0;
1858 for (final Segment<K, V> segment : segments) {
1859 segment.lock();
1860 }
1861 for (final Segment<K, V> segment : segments) {
1862 sum += segment.count;
1863 }
1864 for (final Segment<K, V> segment : segments) {
1865 segment.unlock();
1866 }
1867 }
1868 return sum > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) sum;
1869 }
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881 @Override
1882 public Collection<V> values() {
1883 final Collection<V> vs = values;
1884 return vs != null ? vs : (values = new Values());
1885 }
1886
1887 }