001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018/*
019 * Copyright (c) 2008-2020, Hazelcast, Inc. All Rights Reserved.
020 */
021
022package org.apache.commons.collections4.map;
023
024/*
025 * Written by Doug Lea with assistance from members of JCP JSR-166
026 * Expert Group and released to the public domain, as explained at
027 * http://creativecommons.org/licenses/publicdomain
028 */
029
030import java.lang.ref.Reference;
031import java.lang.ref.ReferenceQueue;
032import java.lang.ref.SoftReference;
033import java.lang.ref.WeakReference;
034import java.util.AbstractCollection;
035import java.util.AbstractMap;
036import java.util.AbstractSet;
037import java.util.Arrays;
038import java.util.Collection;
039import java.util.ConcurrentModificationException;
040import java.util.EnumSet;
041import java.util.Enumeration;
042import java.util.HashMap;
043import java.util.Hashtable;
044import java.util.IdentityHashMap;
045import java.util.Iterator;
046import java.util.Map;
047import java.util.NoSuchElementException;
048import java.util.Objects;
049import java.util.Set;
050import java.util.concurrent.ConcurrentMap;
051import java.util.concurrent.locks.ReentrantLock;
052import java.util.function.BiFunction;
053import java.util.function.Function;
054import java.util.function.Supplier;
055
056/**
057 * An advanced hash map supporting configurable garbage collection semantics of keys and values, optional referential-equality, full concurrency of retrievals,
058 * and adjustable expected concurrency for updates.
059 * <p>
060 * This map is designed around specific advanced use-cases. If there is any doubt whether this map is for you, you most likely should be using
061 * {@link java.util.concurrent.ConcurrentHashMap} instead.
062 * </p>
063 * <p>
064 * This map supports strong, weak, and soft keys and values. By default, keys are weak, and values are strong. Such a configuration offers similar behavior to
065 * {@link java.util.WeakHashMap}, entries of this map are periodically removed once their corresponding keys are no longer referenced outside of this map. In
066 * other words, this map will not prevent a key from being discarded by the garbage collector. Once a key has been discarded by the collector, the corresponding
067 * entry is no longer visible to this map; however, the entry may occupy space until a future map operation decides to reclaim it. For this reason, summary
068 * functions such as {@code size} and {@code isEmpty} might return a value greater than the observed number of entries. In order to support a high level of
069 * concurrency, stale entries are only reclaimed during blocking (usually mutating) operations.
070 * </p>
071 * <p>
072 * Enabling soft keys allows entries in this map to remain until their space is absolutely needed by the garbage collector. This is unlike weak keys which can
073 * be reclaimed as soon as they are no longer referenced by a normal strong reference. The primary use case for soft keys is a cache, which ideally occupies
074 * memory that is not in use for as long as possible.
075 * </p>
076 * <p>
077 * By default, values are held using a normal strong reference. This provides the commonly desired guarantee that a value will always have at least the same
078 * life-span as its key. For this reason, care should be taken to ensure that a value never refers, either directly or indirectly, to its key, thereby
079 * preventing reclamation. If this is unavoidable, then it is recommended to use the same reference type in use for the key. However, it should be noted that
080 * non-strong values may disappear before their corresponding key.
081 * </p>
082 * <p>
083 * While this map does allow the use of both strong keys and values, it is recommended you use {@link java.util.concurrent.ConcurrentHashMap} for such a
084 * configuration, since it is optimized for that case.
085 * </p>
086 * <p>
087 * Just like {@link java.util.concurrent.ConcurrentHashMap}, this class obeys the same functional specification as {@link Hashtable}, and includes versions of
088 * methods corresponding to each method of {@code Hashtable}. However, even though all operations are thread-safe, retrieval operations do <em>not</em> entail
089 * locking, and there is <em>not</em> any support for locking the entire map in a way that prevents all access. This class is fully interoperable with
090 * {@code Hashtable} in programs that rely on its thread safety but not on its synchronization details.
091 * </p>
092 * <p>
093 * Retrieval operations (including {@code get}) generally do not block, so they may overlap with update operations (including {@code put} and {@code remove}).
094 * Retrievals reflect the results of the most recently <em>completed</em> update operations holding upon their onset. For aggregate operations such as
095 * {@code putAll} and {@code clear}, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return
096 * elements reflecting the state of the hash map at some point at or since the creation of the iterator/enumeration. They do <em>not</em> throw
097 * {@link ConcurrentModificationException}. However, iterators are designed to be used by only one thread at a time.
098 * </p>
099 * <p>
100 * The allowed concurrency among update operations is guided by the optional {@code concurrencyLevel} constructor argument (default
101 * {@value #DEFAULT_CONCURRENCY_LEVEL}), which is used as a hint for internal sizing. The map is internally partitioned to try to permit the indicated number of
102 * concurrent updates without contention. Because placement in hash tables is essentially random, the actual concurrency will vary. Ideally, you should choose a
103 * value to accommodate as many threads as will ever concurrently modify the map. Using a significantly higher value than you need can waste space and time, and
104 * a significantly lower value can lead to thread contention. But overestimates and underestimates within an order of magnitude do not usually have much
105 * noticeable impact. A value of one is appropriate when it is known that only one thread will modify and all others will only read. Also, resizing this or any
106 * other kind of hash map is a relatively slow operation, so, when possible, it is a good idea that you provide estimates of expected map sizes in constructors.
107 * </p>
108 * <p>
109 * This class and its views and iterators implement all of the <em>optional</em> methods of the {@link Map} and {@link Iterator} interfaces.
110 * </p>
111 * <p>
112 * Like {@link Hashtable} but unlike {@link HashMap}, this class does <em>not</em> allow {@code null} to be used as a key or value.
113 * </p>
114 * <p>
115 * Provenance: Copied and edited from Apache Groovy git master at commit 77dc80a7512ceb2168b1bc866c3d0c69b002fe11; via Doug Lea, Jason T. Greene, with
116 * assistance from members of JCP JSR-166, and Hazelcast.
117 * </p>
118 *
119 * @param <K> the type of keys maintained by this map.
120 * @param <V> the type of mapped values.
121 */
122public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
123
124    /**
125     * Builds new ConcurrentReferenceHashMap instances.
126     * <p>
127     * By default, keys are weak, and values are strong.
128     * </p>
129     * <p>
130     * The default values are:
131     * </p>
132     * <ul>
133     * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li>
134     * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li>
135     * <li>key reference type: {@link ReferenceType#WEAK}</li>
136     * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li>
137     * <li>options: {@code null}</li>
138     * <li>source map: {@code null}</li>
139     * <li>value reference type: {@link ReferenceType#STRONG}</li>
140     * </ul>
141     *
142     * @param <K> the type of keys.
143     * @param <V> the type of values.
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         * Builds a new {@link ConcurrentReferenceHashMap}.
160         * <p>
161         * By default, keys are weak, and values are strong.
162         * </p>
163         * <p>
164         * The default values are:
165         * </p>
166         * <ul>
167         * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li>
168         * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li>
169         * <li>key reference type: {@link ReferenceType#WEAK}</li>
170         * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li>
171         * <li>options: {@code null}</li>
172         * <li>source map: {@code null}</li>
173         * <li>value reference type: {@link ReferenceType#STRONG}</li>
174         * </ul>
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         * Sets the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this many threads.
188         *
189         * @param concurrencyLevel estimated number of concurrently updating threads
190         * @return this instance.
191         */
192        public Builder<K, V> setConcurrencyLevel(final int concurrencyLevel) {
193            this.concurrencyLevel = concurrencyLevel;
194            return this;
195        }
196
197        /**
198         * Sets the initial capacity. The implementation performs internal sizing to accommodate this many elements.
199         *
200         * @param initialCapacity the initial capacity.
201         * @return this instance.
202         */
203        public Builder<K, V> setInitialCapacity(final int initialCapacity) {
204            this.initialCapacity = initialCapacity;
205            return this;
206        }
207
208        /**
209         * Sets the reference type to use for keys.
210         *
211         * @param keyReferenceType the reference type to use for keys.
212         * @return this instance.
213         */
214        public Builder<K, V> setKeyReferenceType(final ReferenceType keyReferenceType) {
215            this.keyReferenceType = keyReferenceType;
216            return this;
217        }
218
219        /**
220         * Sets the load factor factor, used to control resizing. Resizing may be performed when the average number of elements per bin exceeds this threshold.
221         *
222         * @param loadFactor the load factor factor, used to control resizing
223         * @return this instance.
224         */
225        public Builder<K, V> setLoadFactor(final float loadFactor) {
226            this.loadFactor = loadFactor;
227            return this;
228        }
229
230        /**
231         * Sets the behavioral options.
232         *
233         * @param options the behavioral options.
234         * @return this instance.
235         */
236        public Builder<K, V> setOptions(final EnumSet<Option> options) {
237            this.options = options;
238            return this;
239        }
240
241        /**
242         * Sets the values to load into a new map.
243         *
244         * @param sourceMap the values to load into a new map.
245         * @return this instance.
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         * Sets the reference type to use for values.
254         *
255         * @param valueReferenceType the reference type to use for values.
256         * @return this instance.
257         */
258        public Builder<K, V> setValueReferenceType(final ReferenceType valueReferenceType) {
259            this.valueReferenceType = valueReferenceType;
260            return this;
261        }
262
263        /**
264         * Sets key reference type to {@link ReferenceType#SOFT}.
265         *
266         * @return this instance.
267         */
268        public Builder<K, V> softKeys() {
269            setKeyReferenceType(ReferenceType.SOFT);
270            return this;
271        }
272
273        /**
274         * Sets value reference type to {@link ReferenceType#SOFT}.
275         *
276         * @return this instance.
277         */
278        public Builder<K, V> softValues() {
279            setValueReferenceType(ReferenceType.SOFT);
280            return this;
281        }
282
283        /**
284         * Sets key reference type to {@link ReferenceType#STRONG}.
285         *
286         * @return this instance.
287         */
288        public Builder<K, V> strongKeys() {
289            setKeyReferenceType(ReferenceType.STRONG);
290            return this;
291        }
292
293        /**
294         * Sets value reference type to {@link ReferenceType#STRONG}.
295         *
296         * @return this instance.
297         */
298        public Builder<K, V> strongValues() {
299            setValueReferenceType(ReferenceType.STRONG);
300            return this;
301        }
302
303        /**
304         * Sets key reference type to {@link ReferenceType#WEAK}.
305         *
306         * @return this instance.
307         */
308        public Builder<K, V> weakKeys() {
309            setKeyReferenceType(ReferenceType.WEAK);
310            return this;
311        }
312
313        /**
314         * Sets value reference type to {@link ReferenceType#WEAK}.
315         *
316         * @return this instance.
317         */
318        public Builder<K, V> weakValues() {
319            setValueReferenceType(ReferenceType.WEAK);
320            return this;
321        }
322
323    }
324
325    /**
326     * The basic strategy is to subdivide the table among Segments, each of which itself is a concurrently readable hash table.
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     * ConcurrentReferenceHashMap list entry. Note that this is never exported out as a user-visible Map.Entry.
395     * <p>
396     * Because the value field is volatile, not final, it is legal wrt the Java Memory Model for an unsynchronized reader to see null instead of initial value
397     * when read via a data race. Although a reordering leading to this is not likely to ever actually occur, the Segment.readValueUnderLock method is used as a
398     * backup in case a null (pre-initialized) value is ever seen in an unsynchronized access method.
399     * </p>
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        // Strong reference to weak key (prevents gc)
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 /* Skip GC'd keys */ (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     * Behavior-changing configuration options for the map
619     */
620    public enum Option {
621        /**
622         * Indicates that referential-equality (== instead of .equals()) should be used when locating keys. This offers similar behavior to
623         * {@link IdentityHashMap}
624         */
625        IDENTITY_COMPARISONS
626    }
627
628    /**
629     * An option specifying which Java reference type should be used to refer to a key and/or value.
630     */
631    public enum ReferenceType {
632        /**
633         * Indicates a normal Java strong reference should be used
634         */
635        STRONG,
636        /**
637         * Indicates a {@link WeakReference} should be used
638         */
639        WEAK,
640        /**
641         * Indicates a {@link SoftReference} should be used
642         */
643        SOFT
644    }
645
646    /**
647     * Segments are specialized versions of hash tables. This subclasses from ReentrantLock opportunistically, just to simplify some locking and avoid separate
648     * construction.
649     * <p>
650     * Segments maintain a table of entry lists that are ALWAYS kept in a consistent state, so they can be read without locking. Next fields of nodes are
651     * immutable (final). All list additions are performed at the front of each bin. This makes it easy to check changes, and also fast to traverse. When nodes
652     * would otherwise be changed, new nodes are created to replace them. This works well for hash tables since the bin lists tend to be short. (The average
653     * length is less than two for the default load factor threshold.)
654     * </p>
655     * <p>
656     * Read operations can thus proceed without locking, but rely on selected uses of volatiles to ensure that completed write operations performed by other
657     * threads are noticed. For most purposes, the "count" field, tracking the number of elements, serves as that volatile variable ensuring visibility. This is
658     * convenient because this field needs to be read in many read operations anyway:
659     * </p>
660     * <ul>
661     * <li>All (unsynchronized) read operations must first read the "count" field, and should not look at table entries if it is 0.</li>
662     * <li>All (synchronized) write operations should write to the "count" field after structurally changing any bin. The operations must not take any action
663     * that could even momentarily cause a concurrent read operation to see inconsistent data. This is made easier by the nature of the read operations in Map.
664     * For example, no operation can reveal that the table has grown but the threshold has not yet been updated, so there are no atomicity requirements for this
665     * with respect to reads.</li>
666     * </ul>
667     * <p>
668     * As a guide, all critical volatile reads and writes to the count field are marked in code comments.
669     * </p>
670     *
671     * @param <K> the type of keys maintained by this Segment.
672     * @param <V> the type of mapped values.
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         * The number of elements in this segment's region.
685         */
686        // @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification =
687        // "I trust Doug Lea's technical decision")
688        private transient volatile int count;
689
690        /**
691         * Number of updates that alter the size of the table. This is used during bulk-read methods to make sure they see a consistent snapshot: If modCounts
692         * change during a traversal of segments computing size or checking containsValue, then we might have an inconsistent view of state so (usually) we must
693         * retry.
694         */
695        // @SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification =
696        // "I trust Doug Lea's technical decision")
697        private transient int modCount;
698
699        /**
700         * The table is rehashed when its size exceeds this threshold. (The value of this field is always <code>(int)(capacity *
701         * loadFactor)</code>.)
702         */
703        private transient int threshold;
704
705        /**
706         * The per-segment table.
707         */
708        private transient volatile HashEntry<K, V>[] table;
709
710        /**
711         * The load factor for the hash table. Even though this value is same for all segments, it is replicated to avoid needing links to outer object.
712         */
713        private final float loadFactor;
714
715        /**
716         * The collected weak-key reference queue for this segment. This should be (re)initialized whenever table is assigned,
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                    // delete mapping
743                    if (oldValue != null) {
744                        // something to remove
745                        removeInternal(key, hash, oldValue, false);
746                    }
747                    return null;
748                }
749                // add or replace old mapping
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                    // replace the reference queue to avoid unnecessary stale cleanups
786                    refQueue = new ReferenceQueue<>();
787                    // write-volatile
788                    count = 0;
789                } finally {
790                    unlock();
791                }
792            }
793        }
794
795        boolean containsKey(final Object key, final int hash) {
796            // read-volatile
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            // read-volatile
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                            // recheck
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        /* Specialized implementations of map methods */
834        V get(final Object key, final int hash) {
835            // read-volatile
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                        // recheck
845                        return readValueUnderLock(e);
846                    }
847                    e = e.next;
848                }
849            }
850            return null;
851        }
852
853        /**
854         * Gets properly casted first entry of bin for given hash.
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         * This method must be called with exactly one of <code>value</code> and <code>function</code> non-null.
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            // ensure capacity
889            if (c++ > threshold) {
890                final int reduced = rehash();
891                // adjust from possible weak cleanups
892                if (reduced > 0) {
893                    // write-volatile
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                    // write-volatile
918                    count = c;
919                }
920            }
921            return resultValue;
922        }
923
924        /**
925         * Reads value field of an entry under lock. Called if value field ever appears to be null. This is possible only if a compiler happens to reorder a
926         * HashEntry initialization with its table assignment, which is legal under memory model but is not known to ever occur.
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            // Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the elements from each bin must either stay at the same
946            // index, or move with a power of two offset. We eliminate unnecessary node creation by catching cases where old nodes can be reused because their
947            // next fields won't change. Statistically, at the default threshold, only about one-sixth of them need cloning when a table doubles. The nodes they
948            // replace will be garbage collectable as soon as they are no longer referenced by any reader thread that may be in the midst of traversing table
949            // right now.
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                // We need to guarantee that any existing reads of old Map can
957                // proceed. So we cannot yet null out each bin.
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                    // Single node on list
963                    if (next == null) {
964                        newTable[idx] = e;
965                    } else {
966                        // Reuse trailing consecutive sequence at same slot
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                        // Clone all remaining nodes
978                        for (HashEntry<K, V> p = e; p != lastRun; p = p.next) {
979                            // Skip GC'd weak refs
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         * Removes match on key only if value is null, else match both.
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            // a ref remove operation compares the Reference instance
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                    // All entries following removed node can stay
1028                    // in list, but all preceding ones need to be
1029                    // cloned.
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                        // Skip GC'd keys
1035                        if (pKey == null) {
1036                            c--;
1037                            continue;
1038                        }
1039                        newFirst = newHashEntry(pKey, p.hash, newFirst, p.value());
1040                    }
1041                    tab[index] = newFirst;
1042                    // write-volatile
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         * Sets table to new HashEntry array. Call only while holding lock or in constructor.
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     * A soft-key reference which stores the key hash needed for reclamation.
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     * A weak-key reference which stores the key hash needed for reclamation.
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     * Custom Entry class used by EntryIterator.next(), that relays setValue changes to the underlying map.
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         * Set our entry's value and writes it through to the map. The value to return is somewhat arbitrary: since a WriteThroughEntry does not necessarily
1301         * track asynchronous changes, the most recent "previous" value could be different from what we return (or could even have been removed in which case
1302         * the put will re-establish). We do not and cannot guarantee more.
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     * The default initial capacity for this table, used when not otherwise specified in a constructor.
1323     */
1324    static final int DEFAULT_INITIAL_CAPACITY = 16;
1325
1326    /**
1327     * The default load factor for this table, used when not otherwise specified in a constructor.
1328     */
1329    static final float DEFAULT_LOAD_FACTOR = 0.75f;
1330
1331    /**
1332     * The default concurrency level for this table, used when not otherwise specified in a constructor.
1333     */
1334    static final int DEFAULT_CONCURRENCY_LEVEL = 16;
1335
1336    /**
1337     * The maximum capacity, used if a higher value is implicitly specified by either of the constructors with arguments. MUST be a power of two &lt;=
1338     * 1&lt;&lt;30 to ensure that entries are indexable using ints.
1339     */
1340    private static final int MAXIMUM_CAPACITY = 1 << 30;
1341
1342    /**
1343     * The maximum number of segments to allow; used to bound constructor arguments.
1344     */
1345    private static final int MAX_SEGMENTS = 1 << 16;
1346
1347    /**
1348     * Number of unsynchronized retries in size and containsValue methods before resorting to locking. This is used to avoid unbounded retries if tables undergo
1349     * continuous modification which would make it impossible to obtain an accurate result.
1350     */
1351    private static final int RETRIES_BEFORE_LOCK = 2;
1352
1353    /**
1354     * Creates a new Builder.
1355     * <p>
1356     * By default, keys are weak, and values are strong.
1357     * </p>
1358     * <p>
1359     * The default values are:
1360     * </p>
1361     * <ul>
1362     * <li>concurrency level: {@value #DEFAULT_CONCURRENCY_LEVEL}</li>
1363     * <li>initial capacity: {@value #DEFAULT_INITIAL_CAPACITY}</li>
1364     * <li>key reference type: {@link ReferenceType#WEAK}</li>
1365     * <li>load factor: {@value #DEFAULT_LOAD_FACTOR}</li>
1366     * <li>options: {@code null}</li>
1367     * <li>source map: {@code null}</li>
1368     * <li>value reference type: {@link ReferenceType#STRONG}</li>
1369     * </ul>
1370     *
1371     * @param <K> the type of keys.
1372     * @param <V> the type of values.
1373     * @return a new Builder.
1374     */
1375    public static <K, V> Builder<K, V> builder() {
1376        return new Builder<>();
1377    }
1378
1379    /**
1380     * Applies a supplemental hash function to a given hashCode, which defends against poor quality hash functions. This is critical because
1381     * ConcurrentReferenceHashMap uses power-of-two length hash tables, that otherwise encounter collisions for hashCodes that do not differ in lower or upper
1382     * bits.
1383     */
1384    private static int hash(int h) {
1385        // Spread bits to regularize both segment and index locations,
1386        // using variant of single-word Wang/Jenkins hash.
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     * Mask value for indexing into segments. The upper bits of a key's hash code are used to choose the segment.
1397     */
1398    private final int segmentMask;
1399
1400    /**
1401     * Shift value for indexing within segments.
1402     */
1403    private final int segmentShift;
1404
1405    /**
1406     * The segments, each of which is a specialized hash table
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     * Creates a new, empty map with the specified initial capacity, reference types, load factor, and concurrency level.
1420     * <p>
1421     * Behavioral changing options such as {@link Option#IDENTITY_COMPARISONS} can also be specified.
1422     * </p>
1423     *
1424     * @param initialCapacity  the initial capacity. The implementation performs internal sizing to accommodate this many elements.
1425     * @param loadFactor       the load factor threshold, used to control resizing. Resizing may be performed when the average number of elements per bin
1426     *                         exceeds this threshold.
1427     * @param concurrencyLevel the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this
1428     *                         many threads.
1429     * @param keyType          the reference type to use for keys.
1430     * @param valueType        the reference type to use for values.
1431     * @param options          the behavioral options.
1432     * @throws IllegalArgumentException if the initial capacity is negative or the load factor or concurrencyLevel are nonpositive.
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        // Find power-of-two sizes best matching arguments
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     * Removes all of the mappings from this map.
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     * The default implementation is equivalent to the following steps for this {@code map}, then returning the current value or {@code null} if now absent:
1491     *
1492     * <pre>{@code
1493     * if (map.get(key) == null) {
1494     *     V newValue = mappingFunction.apply(key);
1495     *     if (newValue != null)
1496     *         return map.putIfAbsent(key, newValue);
1497     * }
1498     * }</pre>
1499     * <p>
1500     * The default implementation may retry these steps when multiple threads attempt updates including potentially calling the mapping function multiple times.
1501     * </p>
1502     * <p>
1503     * This implementation assumes that the ConcurrentMap cannot contain null values and {@code get()} returning null unambiguously means the key is absent.
1504     * Implementations which support null values <strong>must</strong> override this default implementation.
1505     * </p>
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     * Tests if the specified object is a key in this table.
1535     *
1536     * @param key possible key
1537     * @return {@code true} if and only if the specified object is a key in this table, as determined by the {@code equals} method; {@code false} otherwise.
1538     * @throws NullPointerException if the specified key is null
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     * Returns {@code true} if this map maps one or more keys to the specified value. Note: This method requires a full internal traversal of the hash table,
1548     * therefore it is much slower than the method {@code containsKey}.
1549     *
1550     * @param value value whose presence in this map is to be tested
1551     * @return {@code true} if this map maps one or more keys to the specified value
1552     * @throws NullPointerException if the specified value is null
1553     */
1554    @Override
1555    public boolean containsValue(final Object value) {
1556        if (value == null) {
1557            throw new NullPointerException();
1558        }
1559        // See explanation of modCount use above
1560        final Segment<K, V>[] segments = this.segments;
1561        final int[] mc = new int[segments.length];
1562        // Try a few times without locking
1563        for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
1564            // final int sum = 0;
1565            int mcsum = 0;
1566            for (int i = 0; i < segments.length; ++i) {
1567                // final int c = segments[i].count;
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                    // final int c = segments[i].count;
1577                    if (mc[i] != segments[i].modCount) {
1578                        cleanSweep = false;
1579                        break;
1580                    }
1581                }
1582            }
1583            if (cleanSweep) {
1584                return false;
1585            }
1586        }
1587        // Resort to locking all segments
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     * Returns a {@link Set} view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and
1609     * vice-versa. The set supports element removal, which removes the corresponding mapping from the map, via the {@code Iterator.remove}, {@code Set.remove},
1610     * {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations.
1611     * <p>
1612     * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and is guaranteed to
1613     * traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to
1614     * construction.
1615     * </p>
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     * Returns the value to which the specified key is mapped, or {@code null} if this map contains no mapping for the key.
1625     * <p>
1626     * If this map contains a mapping from a key {@code k} to a value {@code v} such that {@code key.equals(k)}, then this method returns {@code v}; otherwise
1627     * it returns {@code null}. (There can be at most one such mapping.)
1628     * </p>
1629     *
1630     * @throws NullPointerException if the specified key is null
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     * Returns {@code true} if this map contains no key-value mappings.
1644     *
1645     * @return {@code true} if this map contains no key-value mappings
1646     */
1647    @Override
1648    public boolean isEmpty() {
1649        final Segment<K, V>[] segments = this.segments;
1650        //
1651        // We keep track of per-segment modCounts to avoid ABA problems in which an element in one segment was added and in another removed during traversal, in
1652        // which case the table was never actually empty at any point. Note the similar use of modCounts in the size() and containsValue() methods, which are
1653        // the only other methods also susceptible to ABA problems.
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        // If mcsum happens to be zero, then we know we got a snapshot
1664        // before any modifications at all were made. This is
1665        // probably common enough to bother tracking.
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     * Returns a {@link Set} view of the keys contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and
1678     * vice-versa. The set supports element removal, which removes the corresponding mapping from this map, via the {@code Iterator.remove}, {@code Set.remove},
1679     * {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the {@code add} or {@code addAll} operations.
1680     * <p>
1681     * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and guarantees to traverse
1682     * elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.
1683     * </p>
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     * Removes any stale entries whose keys have been finalized. Use of this method is normally not necessary since stale entries are automatically removed
1693     * lazily, when blocking operations are required. However, there are some cases where this operation should be performed eagerly, such as cleaning up old
1694     * references to a ClassLoader in a multi-classloader environment.
1695     * <p>
1696     * Note: this method will acquire locks one at a time across all segments of this table, so this method should be used sparingly.
1697     * </p>
1698     */
1699    public void purgeStaleEntries() {
1700        for (final Segment<K, V> segment : segments) {
1701            segment.removeStale();
1702        }
1703    }
1704
1705    /**
1706     * Maps the specified key to the specified value in this table. Neither the key nor the value can be null.
1707     * <p>
1708     * The value can be retrieved by calling the {@code get} method with a key that is equal to the original key.
1709     * </p>
1710     *
1711     * @param key   key with which the specified value is to be associated
1712     * @param value value to be associated with the specified key
1713     * @return the previous value associated with {@code key}, or {@code null} if there was no mapping for {@code key}
1714     * @throws NullPointerException if the specified key or value is null
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     * Copies all of the mappings from the specified map to this one. These mappings replace any mappings that this map had for any of the keys currently in the
1727     * specified map.
1728     *
1729     * @param m mappings to be stored in this map
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     * {@inheritDoc}
1740     *
1741     * @return the previous value associated with the specified key, or {@code null} if there was no mapping for the key
1742     * @throws NullPointerException if the specified key or value is null
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     * Removes the key (and its corresponding value) from this map. This method does nothing if the key is not in the map.
1755     *
1756     * @param key the key that needs to be removed
1757     * @return the previous value associated with {@code key}, or {@code null} if there was no mapping for {@code key}
1758     * @throws NullPointerException if the specified key is null
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     * {@inheritDoc}
1768     *
1769     * @throws NullPointerException if the specified key is null
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     * {@inheritDoc}
1782     *
1783     * @return the previous value associated with the specified key, or {@code null} if there was no mapping for the key
1784     * @throws NullPointerException if the specified key or value is null
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     * {@inheritDoc}
1797     *
1798     * @throws NullPointerException if any of the arguments are null
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     * Returns the segment that should be used for key with given hash
1811     *
1812     * @param hash the hash code for the key
1813     * @return the segment
1814     */
1815    private Segment<K, V> segmentFor(final int hash) {
1816        return segments[hash >>> segmentShift & segmentMask];
1817    }
1818
1819    /**
1820     * Returns the number of key-value mappings in this map. If the map contains more than {@code Integer.MAX_VALUE} elements, returns
1821     * {@code Integer.MAX_VALUE}.
1822     *
1823     * @return the number of key-value mappings in this map
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        // Try a few times to get accurate count. On failure due to
1832        // continuous async changes in table, resort to locking.
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                        // force retry
1846                        check = -1;
1847                        break;
1848                    }
1849                }
1850            }
1851            if (check == sum) {
1852                break;
1853            }
1854        }
1855        if (check != sum) {
1856            // Resort to locking all segments
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     * Returns a {@link Collection} view of the values contained in this map. The collection is backed by the map, so changes to the map are reflected in the
1873     * collection, and vice-versa. The collection supports element removal, which removes the corresponding mapping from this map, via the
1874     * {@code Iterator.remove}, {@code Collection.remove}, {@code removeAll}, {@code retainAll}, and {@code clear} operations. It does not support the
1875     * {@code add} or {@code addAll} operations.
1876     * <p>
1877     * The view's {@code iterator} is a "weakly consistent" iterator that will never throw {@link ConcurrentModificationException}, and guarantees to traverse
1878     * elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.
1879     * </p>
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}