1/*
2 * Copyright (C) 2009 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect;
18
19import com.google.common.base.Function;
20
21import java.io.IOException;
22import java.io.Serializable;
23import java.lang.reflect.Array;
24import java.lang.reflect.Field;
25import java.util.AbstractCollection;
26import java.util.AbstractMap;
27import java.util.AbstractSet;
28import java.util.Collection;
29import java.util.Iterator;
30import java.util.Map;
31import java.util.NoSuchElementException;
32import java.util.Set;
33import java.util.concurrent.ConcurrentHashMap;
34import java.util.concurrent.ConcurrentMap;
35import java.util.concurrent.atomic.AtomicReferenceArray;
36import java.util.concurrent.locks.ReentrantLock;
37
38import javax.annotation.Nullable;
39
40/**
41 * A framework for concurrent hash map implementations. The
42 * CustomConcurrentHashMap class itself is not extensible and does not contain
43 * any methods. Use {@link Builder} to create a custom concurrent hash map
44 * instance. Client libraries implement {@link Strategy}, and this class
45 * provides the surrounding concurrent data structure which implements {@link
46 * ConcurrentMap}. Additionally supports implementing maps where {@link
47 * Map#get} atomically computes values on demand (see {@link
48 * Builder#buildComputingMap(CustomConcurrentHashMap.ComputingStrategy,
49 * Function)}).
50 *
51 * <p>The resulting hash table supports full concurrency of retrievals and
52 * adjustable expected concurrency for updates. Even though all operations are
53 * thread-safe, retrieval operations do <i>not</i> entail locking,
54 * and there is <i>not</i> any support for locking the entire table
55 * in a way that prevents all access.
56 *
57 * <p>Retrieval operations (including {@link Map#get}) generally do not
58 * block, so may overlap with update operations (including
59 * {@link Map#put} and {@link Map#remove}). Retrievals reflect the results
60 * of the most recently <i>completed</i> update operations holding
61 * upon their onset. For aggregate operations such as {@link Map#putAll}
62 * and {@link Map#clear}, concurrent retrievals may reflect insertion or
63 * removal of only some entries. Similarly, iterators return elements
64 * reflecting the state of the hash table at some point at or since the
65 * creation of the iterator. They do <i>not</i> throw
66 * {@link java.util.ConcurrentModificationException}. However, iterators can
67 * only be used by one thread at a time.
68 *
69 * <p>The resulting {@link ConcurrentMap} and its views and iterators implement
70 * all of the <i>optional</i> methods of the {@link java.util.Map} and {@link
71 * java.util.Iterator} interfaces. Partially reclaimed entries are never
72 * exposed through the views or iterators.
73 *
74 * <p>For example, the following strategy emulates the behavior of
75 * {@link java.util.concurrent.ConcurrentHashMap}:
76 *
77 * <pre> {@code
78 * class ConcurrentHashMapStrategy<K, V>
79 *     implements CustomConcurrentHashMap.Strategy<K, V,
80 *     InternalEntry<K, V>>, Serializable {
81 *   public InternalEntry<K, V> newEntry(K key, int hash,
82 *       InternalEntry<K, V> next) {
83 *     return new InternalEntry<K, V>(key, hash, null, next);
84 *   }
85 *   public InternalEntry<K, V> copyEntry(K key,
86 *       InternalEntry<K, V> original, InternalEntry<K, V> next) {
87 *     return new InternalEntry<K, V>(key, original.hash, original.value, next);
88 *   }
89 *   public void setValue(InternalEntry<K, V> entry, V value) {
90 *     entry.value = value;
91 *   }
92 *   public V getValue(InternalEntry<K, V> entry) { return entry.value; }
93 *   public boolean equalKeys(K a, Object b) { return a.equals(b); }
94 *   public boolean equalValues(V a, Object b) { return a.equals(b); }
95 *   public int hashKey(Object key) { return key.hashCode(); }
96 *   public K getKey(InternalEntry<K, V> entry) { return entry.key; }
97 *   public InternalEntry<K, V> getNext(InternalEntry<K, V> entry) {
98 *     return entry.next;
99 *   }
100 *   public int getHash(InternalEntry<K, V> entry) { return entry.hash; }
101 *   public void setInternals(CustomConcurrentHashMap.Internals<K, V,
102 *       InternalEntry<K, V>> internals) {} // ignored
103 * }
104 *
105 * class InternalEntry<K, V> {
106 *   final K key;
107 *   final int hash;
108 *   volatile V value;
109 *   final InternalEntry<K, V> next;
110 *   InternalEntry(K key, int hash, V value, InternalEntry<K, V> next) {
111 *     this.key = key;
112 *     this.hash = hash;
113 *     this.value = value;
114 *     this.next = next;
115 *   }
116 * }
117 * }</pre>
118 *
119 * To create a {@link java.util.concurrent.ConcurrentMap} using the strategy
120 * above:
121 *
122 * <pre>{@code
123 *   ConcurrentMap<K, V> map = new CustomConcurrentHashMap.Builder()
124 *       .build(new ConcurrentHashMapStrategy<K, V>());
125 * }</pre>
126 *
127 * @author Bob Lee
128 * @author Doug Lea
129 */
130final class CustomConcurrentHashMap {
131
132  /** Prevents instantiation. */
133  private CustomConcurrentHashMap() {}
134
135  /**
136   * Builds a custom concurrent hash map.
137   */
138  static final class Builder {
139    private static final int DEFAULT_INITIAL_CAPACITY = 16;
140    private static final int DEFAULT_CONCURRENCY_LEVEL = 16;
141
142    private static final int UNSET_INITIAL_CAPACITY = -1;
143    private static final int UNSET_CONCURRENCY_LEVEL = -1;
144
145    int initialCapacity = UNSET_INITIAL_CAPACITY;
146    int concurrencyLevel = UNSET_CONCURRENCY_LEVEL;
147
148    /**
149     * Sets a custom initial capacity (defaults to 16). Resizing this or any
150     * other kind of hash table is a relatively slow operation, so, when
151     * possible, it is a good idea to provide estimates of expected table
152     * sizes.
153     *
154     * @throws IllegalArgumentException if initialCapacity < 0
155     */
156    public Builder initialCapacity(int initialCapacity) {
157      if (this.initialCapacity != UNSET_INITIAL_CAPACITY) {
158        throw new IllegalStateException(
159            "initial capacity was already set to " + this.initialCapacity);
160      }
161      if (initialCapacity < 0) {
162        throw new IllegalArgumentException();
163      }
164      this.initialCapacity = initialCapacity;
165      return this;
166    }
167
168    /**
169     * Guides the allowed concurrency among update operations. Used as a
170     * hint for internal sizing. The table is internally partitioned to try to
171     * permit the indicated number of concurrent updates without contention.
172     * Because placement in hash tables is essentially random, the actual
173     * concurrency will vary. Ideally, you should choose a value to accommodate
174     * as many threads as will ever concurrently modify the table. Using a
175     * significantly higher value than you need can waste space and time,
176     * and a significantly lower value can lead to thread contention. But
177     * overestimates and underestimates within an order of magnitude do
178     * not usually have much noticeable impact. A value of one is
179     * appropriate when it is known that only one thread will modify and
180     * all others will only read. Defaults to {@literal 16}.
181     *
182     * @throws IllegalArgumentException if concurrencyLevel < 0
183     */
184    public Builder concurrencyLevel(int concurrencyLevel) {
185      if (this.concurrencyLevel != UNSET_CONCURRENCY_LEVEL) {
186        throw new IllegalStateException(
187            "concurrency level was already set to " + this.concurrencyLevel);
188      }
189      if (concurrencyLevel <= 0) {
190        throw new IllegalArgumentException();
191      }
192      this.concurrencyLevel = concurrencyLevel;
193      return this;
194    }
195
196    /**
197     * Creates a new concurrent hash map backed by the given strategy.
198     *
199     * @param strategy used to implement and manipulate the entries
200     *
201     * @param <K> the type of keys to be stored in the returned map
202     * @param <V> the type of values to be stored in the returned map
203     * @param <E> the type of internal entry to be stored in the returned map
204     *
205     * @throws NullPointerException if strategy is null
206     */
207    public <K, V, E> ConcurrentMap<K, V> buildMap(Strategy<K, V, E> strategy) {
208      if (strategy == null) {
209        throw new NullPointerException("strategy");
210      }
211      return new Impl<K, V, E>(strategy, this);
212    }
213
214    /**
215     * Creates a {@link ConcurrentMap}, backed by the given strategy, that
216     * supports atomic, on-demand computation of values. {@link Map#get}
217     * returns the value corresponding to the given key, atomically computes
218     * it using the computer function passed to this builder, or waits for
219     * another thread to compute the value if necessary. Only one value will
220     * be computed for each key at a given time.
221     *
222     * <p>If an entry's value has not finished computing yet, query methods
223     * besides {@link java.util.Map#get} return immediately as if an entry
224     * doesn't exist. In other words, an entry isn't externally visible until
225     * the value's computation completes.
226     *
227     * <p>{@link Map#get} in the returned map implementation throws:
228     * <ul>
229     * <li>{@link NullPointerException} if the key is null or the
230     *  computer returns null</li>
231     * <li>or {@link ComputationException} wrapping an exception thrown by the
232     *  computation</li>
233     * </ul>
234     *
235     * <p><b>Note:</b> Callers of {@code get()} <i>must</i> ensure that the key
236     *  argument is of type {@code K}. {@code Map.get()} takes {@code Object},
237     *  so the key type is not checked at compile time. Passing an object of
238     *  a type other than {@code K} can result in that object being unsafely
239     *  passed to the computer function as type {@code K} not to mention the
240     *  unsafe key being stored in the map.
241     *
242     * @param strategy used to implement and manipulate the entries
243     * @param computer used to compute values for keys
244     *
245     * @param <K> the type of keys to be stored in the returned map
246     * @param <V> the type of values to be stored in the returned map
247     * @param <E> the type of internal entry to be stored in the returned map
248     *
249     * @throws NullPointerException if strategy or computer is null
250     */
251    public <K, V, E> ConcurrentMap<K, V> buildComputingMap(
252        ComputingStrategy<K, V, E> strategy,
253        Function<? super K, ? extends V> computer) {
254      if (strategy == null) {
255        throw new NullPointerException("strategy");
256      }
257      if (computer == null) {
258        throw new NullPointerException("computer");
259      }
260
261      return new ComputingImpl<K, V, E>(strategy, this, computer);
262    }
263
264    int getInitialCapacity() {
265      return (initialCapacity == UNSET_INITIAL_CAPACITY)
266          ? DEFAULT_INITIAL_CAPACITY : initialCapacity;
267    }
268
269    int getConcurrencyLevel() {
270      return (concurrencyLevel == UNSET_CONCURRENCY_LEVEL)
271          ? DEFAULT_CONCURRENCY_LEVEL : concurrencyLevel;
272    }
273  }
274
275  /**
276   * Implements behavior specific to the client's concurrent hash map
277   * implementation. Used by the framework to create new entries and perform
278   * operations on them.
279   *
280   * <p>Method parameters are never null unless otherwise specified.
281   *
282   * <h3>Partially Reclaimed Entries</h3>
283   *
284   * <p>This class does <i>not</i> allow {@code null} to be used as a key.
285   * Setting values to null is not permitted, but entries may have null keys
286   * or values for various reasons. For example, the key or value may have
287   * been garbage collected or reclaimed through other means.
288   * CustomConcurrentHashMap treats entries with null keys and values as
289   * "partially reclaimed" and ignores them for the most part. Entries may
290   * enter a partially reclaimed state but they must not leave it. Partially
291   * reclaimed entries will not be copied over during table expansions, for
292   * example. Strategy implementations should proactively remove partially
293   * reclaimed entries so that {@link Map#isEmpty} and {@link Map#size()}
294   * return up-to-date results.
295   *
296   * @param <K> the type of keys to be stored in the returned map
297   * @param <V> the type of values to be stored in the returned map
298   * @param <E> internal entry type, not directly exposed to clients in map
299   *  views
300   */
301  public interface Strategy<K, V, E> {
302
303    /**
304     * Constructs a new entry for the given key with a pointer to the given
305     * next entry.
306     *
307     * <p>This method may return different entry implementations
308     * depending upon whether next is null or not. For example, if next is
309     * null (as will often be the case), this factory might use an entry
310     * class that doesn't waste memory on an unnecessary field.
311     *
312     * @param key for this entry
313     * @param hash of key returned by {@link #hashKey}
314     * @param next entry (used when implementing a hash bucket as a linked
315     *  list, for example), possibly null
316     * @return a new entry
317     */
318    abstract E newEntry(K key, int hash, E next);
319
320    /**
321     * Creates a copy of the given entry pointing to the given next entry.
322     * Copies the value and any other implementation-specific state from
323     * {@code original} to the returned entry. For example,
324     * CustomConcurrentHashMap might use this method when removing other
325     * entries or expanding the internal table.
326     *
327     * @param key for {@code original} as well as the returned entry.
328     *  Explicitly provided here to prevent reclamation of the key at an
329     *  inopportune time in implementations that don't otherwise keep
330     *  a strong reference to the key.
331     * @param original entry from which the value and other
332     *  implementation-specific state should be copied
333     * @param newNext the next entry the new entry should point to, possibly
334     *  null
335     */
336    E copyEntry(K key, E original, E newNext);
337
338    /**
339     * Sets the value of an entry using volatile semantics. Values are set
340     * synchronously on a per-entry basis.
341     *
342     * @param entry to set the value on
343     * @param value to set
344     */
345    void setValue(E entry, V value);
346
347    /**
348     * Gets the value of an entry using volatile semantics.
349     *
350     * @param entry to get the value from
351     */
352    V getValue(E entry);
353
354    /**
355     * Returns true if the two given keys are equal, false otherwise. Neither
356     * key will be null.
357     *
358     * @param a key from inside the map
359     * @param b key passed from caller, not necesarily of type K
360     *
361     * @see Object#equals the same contractual obligations apply here
362     */
363    boolean equalKeys(K a, Object b);
364
365    /**
366     * Returns true if the two given values are equal, false otherwise. Neither
367     * value will be null.
368     *
369     * @param a value from inside the map
370     * @param b value passed from caller, not necesarily of type V
371     *
372     * @see Object#equals the same contractual obligations apply here
373     */
374    boolean equalValues(V a, Object b);
375
376    /**
377     * Returns a hash code for the given key.
378     *
379     * @see Object#hashCode the same contractual obligations apply here
380     */
381    int hashKey(Object key);
382
383    /**
384     * Gets the key for the given entry. This may return null (for example,
385     * if the key was reclaimed by the garbage collector).
386     *
387     * @param entry to get key from
388     * @return key from the given entry
389     */
390    K getKey(E entry);
391
392    /**
393     * Gets the next entry relative to the given entry, the exact same entry
394     * that was provided to {@link Strategy#newEntry} when the given entry was
395     * created.
396     *
397     * @return the next entry or null if null was passed to
398     *  {@link Strategy#newEntry}
399     */
400    E getNext(E entry);
401
402    /**
403     * Returns the hash code that was passed to {@link Strategy#newEntry})
404     * when the given entry was created.
405     */
406    int getHash(E entry);
407
408// TODO:
409//    /**
410//     * Notifies the strategy that an entry has been removed from the map.
411//     *
412//     * @param entry that was recently removed
413//     */
414//    void remove(E entry);
415
416    /**
417     * Provides an API for interacting directly with the map's internal
418     * entries to this strategy. Invoked once when the map is created.
419     * Strategies that don't need access to the map's internal entries
420     * can simply ignore the argument.
421     *
422     * @param internals of the map, enables direct interaction with the
423     *  internal entries
424     */
425    void setInternals(Internals<K, V, E> internals);
426  }
427
428  /**
429   * Provides access to a map's internal entries.
430   */
431  public interface Internals<K, V, E> {
432
433// TODO:
434//    /**
435//     * Returns a set view of the internal entries.
436//     */
437//    Set<E> entrySet();
438
439    /**
440     * Returns the internal entry corresponding to the given key from the map.
441     *
442     * @param key to retrieve entry for
443     *
444     * @throws NullPointerException if key is null
445     */
446    E getEntry(K key);
447
448    /**
449     * Removes the given entry from the map if the value of the entry in the
450     * map matches the given value.
451     *
452     * @param entry to remove
453     * @param value entry must have for the removal to succeed
454     *
455     * @throws NullPointerException if entry is null
456     */
457    boolean removeEntry(E entry, @Nullable V value);
458
459    /**
460     * Removes the given entry from the map.
461     *
462     * @param entry to remove
463     *
464     * @throws NullPointerException if entry is null
465     */
466    boolean removeEntry(E entry);
467  }
468
469  /**
470   * Extends {@link Strategy} to add support for computing values on-demand.
471   * Implementations should typically intialize the entry's value to a
472   * placeholder value in {@link #newEntry(Object, int, Object)} so that
473   * {@link #waitForValue(Object)} can tell the difference between a
474   * pre-intialized value and an in-progress computation. {@link
475   * #copyEntry(Object, Object, Object)} must detect and handle the case where
476   * an entry is copied in the middle of a computation. Implementations can
477   * throw {@link UnsupportedOperationException} in {@link #setValue(Object,
478   * Object)} if they wish to prevent users from setting values directly.
479   *
480   * @see Builder#buildComputingMap(CustomConcurrentHashMap.ComputingStrategy,
481   *     Function)
482   */
483  public interface ComputingStrategy<K, V, E> extends Strategy<K, V, E> {
484
485    /**
486     * Computes a value for the given key and stores it in the given entry.
487     * Called as a result of {@link Map#get}. If this method throws an
488     * exception, CustomConcurrentHashMap will remove the entry and retry
489     * the computation on subsequent requests.
490     *
491     * @param entry that was created
492     * @param computer passed to {@link Builder#buildMap}
493     *
494     * @throws ComputationException if the computation threw an exception
495     * @throws NullPointerException if the computer returned null
496     *
497     * @return the computed value
498     */
499    V compute(K key, E entry, Function<? super K, ? extends V> computer);
500
501    /**
502     * Gets a value from an entry waiting for the value to be set by {@link
503     * #compute} if necessary. Returns null if a value isn't available at
504     * which point CustomConcurrentHashMap tries to compute a new value.
505     *
506     * @param entry to return value from
507     * @return stored value or null if the value isn't available
508     *
509     * @throws InterruptedException if the thread was interrupted while
510     *  waiting
511     */
512    V waitForValue(E entry) throws InterruptedException;
513  }
514
515  /**
516   * Applies a supplemental hash function to a given hash code, which defends
517   * against poor quality hash functions. This is critical when the
518   * concurrent hash map uses power-of-two length hash tables, that otherwise
519   * encounter collisions for hash codes that do not differ in lower or upper
520   * bits.
521   *
522   * @param h hash code
523   */
524  private static int rehash(int h) {
525    // Spread bits to regularize both segment and index locations,
526    // using variant of single-word Wang/Jenkins hash.
527    h += (h << 15) ^ 0xffffcd7d;
528    h ^= (h >>> 10);
529    h += (h << 3);
530    h ^= (h >>> 6);
531    h += (h << 2) + (h << 14);
532    return h ^ (h >>> 16);
533  }
534
535  /** The concurrent hash map implementation. */
536  static class Impl<K, V, E> extends AbstractMap<K, V>
537      implements ConcurrentMap<K, V>, Serializable {
538
539    /*
540     * The basic strategy is to subdivide the table among Segments,
541     * each of which itself is a concurrently readable hash table.
542     */
543
544    /* ---------------- Constants -------------- */
545
546    /**
547     * The maximum capacity, used if a higher value is implicitly specified by
548     * either of the constructors with arguments.  MUST be a power of two <=
549     * 1<<30 to ensure that entries are indexable using ints.
550     */
551    static final int MAXIMUM_CAPACITY = 1 << 30;
552
553    /**
554     * The maximum number of segments to allow; used to bound constructor
555     * arguments.
556     */
557    static final int MAX_SEGMENTS = 1 << 16; // slightly conservative
558
559    /**
560     * Number of unsynchronized retries in size and containsValue methods before
561     * resorting to locking. This is used to avoid unbounded retries if tables
562     * undergo continuous modification which would make it impossible to obtain
563     * an accurate result.
564     */
565    static final int RETRIES_BEFORE_LOCK = 2;
566
567    /* ---------------- Fields -------------- */
568
569    /**
570     * The strategy used to implement this map.
571     */
572    final Strategy<K, V, E> strategy;
573
574    /**
575     * Mask value for indexing into segments. The upper bits of a key's hash
576     * code are used to choose the segment.
577     */
578    final int segmentMask;
579
580    /**
581     * Shift value for indexing within segments. Helps prevent entries that
582     * end up in the same segment from also ending up in the same bucket.
583     */
584    final int segmentShift;
585
586    /**
587     * The segments, each of which is a specialized hash table
588     */
589    final Segment[] segments;
590
591    /**
592     * Creates a new, empty map with the specified strategy, initial capacity,
593     * load factor and concurrency level.
594     */
595    Impl(Strategy<K, V, E> strategy, Builder builder) {
596      int concurrencyLevel = builder.getConcurrencyLevel();
597      int initialCapacity = builder.getInitialCapacity();
598
599      if (concurrencyLevel > MAX_SEGMENTS) {
600        concurrencyLevel = MAX_SEGMENTS;
601      }
602
603      // Find power-of-two sizes best matching arguments
604      int segmentShift = 0;
605      int segmentCount = 1;
606      while (segmentCount < concurrencyLevel) {
607        ++segmentShift;
608        segmentCount <<= 1;
609      }
610      this.segmentShift = 32 - segmentShift;
611      segmentMask = segmentCount - 1;
612      this.segments = newSegmentArray(segmentCount);
613
614      if (initialCapacity > MAXIMUM_CAPACITY) {
615        initialCapacity = MAXIMUM_CAPACITY;
616      }
617
618      int segmentCapacity = initialCapacity / segmentCount;
619      if (segmentCapacity * segmentCount < initialCapacity) {
620        ++segmentCapacity;
621      }
622
623      int segmentSize = 1;
624      while (segmentSize < segmentCapacity) {
625          segmentSize <<= 1;
626      }
627      for (int i = 0; i < this.segments.length; ++i) {
628        this.segments[i] = new Segment(segmentSize);
629      }
630
631      this.strategy = strategy;
632
633      strategy.setInternals(new InternalsImpl());
634    }
635
636    int hash(Object key) {
637      int h = strategy.hashKey(key);
638      return rehash(h);
639    }
640
641    class InternalsImpl implements Internals<K, V, E>, Serializable {
642
643      static final long serialVersionUID = 0;
644
645      public E getEntry(K key) {
646        if (key == null) {
647          throw new NullPointerException("key");
648        }
649        int hash = hash(key);
650        return segmentFor(hash).getEntry(key, hash);
651      }
652
653      public boolean removeEntry(E entry, V value) {
654        if (entry == null) {
655          throw new NullPointerException("entry");
656        }
657        int hash = strategy.getHash(entry);
658        return segmentFor(hash).removeEntry(entry, hash, value);
659      }
660
661      public boolean removeEntry(E entry) {
662        if (entry == null) {
663          throw new NullPointerException("entry");
664        }
665        int hash = strategy.getHash(entry);
666        return segmentFor(hash).removeEntry(entry, hash);
667      }
668    }
669
670    @SuppressWarnings("unchecked")
671    Segment[] newSegmentArray(int ssize) {
672      // Note: This is the only way I could figure out how to create
673      // a segment array (the compile has a tough time with arrays of
674      // inner classes of generic types apparently). Safe because we're
675      // restricting what can go in the array and no one has an
676      // unrestricted reference.
677      return (Segment[]) Array.newInstance(Segment.class, ssize);
678    }
679
680    /* ---------------- Small Utilities -------------- */
681
682    /**
683     * Returns the segment that should be used for key with given hash
684     *
685     * @param hash the hash code for the key
686     * @return the segment
687     */
688    Segment segmentFor(int hash) {
689      return segments[(hash >>> segmentShift) & segmentMask];
690    }
691
692    /* ---------------- Inner Classes -------------- */
693
694    /**
695     * Segments are specialized versions of hash tables.  This subclasses from
696     * ReentrantLock opportunistically, just to simplify some locking and avoid
697     * separate construction.
698     */
699    @SuppressWarnings("serial") // This class is never serialized.
700    final class Segment extends ReentrantLock {
701
702      /*
703       * Segments maintain a table of entry lists that are ALWAYS
704       * kept in a consistent state, so can be read without locking.
705       * Next fields of nodes are immutable (final).  All list
706       * additions are performed at the front of each bin. This
707       * makes it easy to check changes, and also fast to traverse.
708       * When nodes would otherwise be changed, new nodes are
709       * created to replace them. This works well for hash tables
710       * since the bin lists tend to be short. (The average length
711       * is less than two for the default load factor threshold.)
712       *
713       * Read operations can thus proceed without locking, but rely
714       * on selected uses of volatiles to ensure that completed
715       * write operations performed by other threads are
716       * noticed. For most purposes, the "count" field, tracking the
717       * number of elements, serves as that volatile variable
718       * ensuring visibility.  This is convenient because this field
719       * needs to be read in many read operations anyway:
720       *
721       *   - All (unsynchronized) read operations must first read the
722       *     "count" field, and should not look at table entries if
723       *     it is 0.
724       *
725       *   - All (synchronized) write operations should write to
726       *     the "count" field after structurally changing any bin.
727       *     The operations must not take any action that could even
728       *     momentarily cause a concurrent read operation to see
729       *     inconsistent data. This is made easier by the nature of
730       *     the read operations in Map. For example, no operation
731       *     can reveal that the table has grown but the threshold
732       *     has not yet been updated, so there are no atomicity
733       *     requirements for this with respect to reads.
734       *
735       * As a guide, all critical volatile reads and writes to the
736       * count field are marked in code comments.
737       */
738
739      /**
740       * The number of elements in this segment's region.
741       */
742      volatile int count;
743
744      /**
745       * Number of updates that alter the size of the table. This is used
746       * during bulk-read methods to make sure they see a consistent snapshot:
747       * If modCounts change during a traversal of segments computing size or
748       * checking containsValue, then we might have an inconsistent view of
749       * state so (usually) must retry.
750       */
751      int modCount;
752
753      /**
754       * The table is expanded when its size exceeds this threshold. (The
755       * value of this field is always {@code (int)(capacity * loadFactor)}.)
756       */
757      int threshold;
758
759      /**
760       * The per-segment table.
761       */
762      volatile AtomicReferenceArray<E> table;
763
764      Segment(int initialCapacity) {
765        setTable(newEntryArray(initialCapacity));
766      }
767
768      AtomicReferenceArray<E> newEntryArray(int size) {
769        return new AtomicReferenceArray<E>(size);
770      }
771
772      /**
773       * Sets table to new HashEntry array. Call only while holding lock or in
774       * constructor.
775       */
776      void setTable(AtomicReferenceArray<E> newTable) {
777        this.threshold = newTable.length() * 3 / 4;
778        this.table = newTable;
779      }
780
781      /**
782       * Returns properly casted first entry of bin for given hash.
783       */
784      E getFirst(int hash) {
785        AtomicReferenceArray<E> table = this.table;
786        return table.get(hash & (table.length() - 1));
787      }
788
789      /* Specialized implementations of map methods */
790
791      public E getEntry(Object key, int hash) {
792        Strategy<K, V, E> s = Impl.this.strategy;
793        if (count != 0) { // read-volatile
794          for (E e = getFirst(hash); e != null; e = s.getNext(e)) {
795            if (s.getHash(e) != hash) {
796              continue;
797            }
798
799            K entryKey = s.getKey(e);
800            if (entryKey == null) {
801              continue;
802            }
803
804            if (s.equalKeys(entryKey, key)) {
805              return e;
806            }
807          }
808        }
809
810        return null;
811      }
812
813      V get(Object key, int hash) {
814        E entry = getEntry(key, hash);
815        if (entry == null) {
816          return null;
817        }
818
819        return strategy.getValue(entry);
820      }
821
822      boolean containsKey(Object key, int hash) {
823        Strategy<K, V, E> s = Impl.this.strategy;
824        if (count != 0) { // read-volatile
825          for (E e = getFirst(hash); e != null; e = s.getNext(e)) {
826            if (s.getHash(e) != hash) {
827              continue;
828            }
829
830            K entryKey = s.getKey(e);
831            if (entryKey == null) {
832              continue;
833            }
834
835            if (s.equalKeys(entryKey, key)) {
836              // Return true only if this entry has a value.
837              return s.getValue(e) != null;
838            }
839          }
840        }
841
842        return false;
843      }
844
845      boolean containsValue(Object value) {
846        Strategy<K, V, E> s = Impl.this.strategy;
847        if (count != 0) { // read-volatile
848          AtomicReferenceArray<E> table = this.table;
849          int length = table.length();
850          for (int i = 0; i < length; i++) {
851            for (E e = table.get(i); e != null; e = s.getNext(e)) {
852              V entryValue = s.getValue(e);
853
854              // If the value disappeared, this entry is partially collected,
855              // and we should skip it.
856              if (entryValue == null) {
857                continue;
858              }
859
860              if (s.equalValues(entryValue, value)) {
861                return true;
862              }
863            }
864          }
865        }
866
867        return false;
868      }
869
870      boolean replace(K key, int hash, V oldValue, V newValue) {
871        Strategy<K, V, E> s = Impl.this.strategy;
872        lock();
873        try {
874          for (E e = getFirst(hash); e != null; e = s.getNext(e)) {
875            K entryKey = s.getKey(e);
876            if (s.getHash(e) == hash && entryKey != null
877                && s.equalKeys(key, entryKey)) {
878              // If the value disappeared, this entry is partially collected,
879              // and we should pretend like it doesn't exist.
880              V entryValue = s.getValue(e);
881              if (entryValue == null) {
882                return false;
883              }
884
885              if (s.equalValues(entryValue, oldValue)) {
886                s.setValue(e, newValue);
887                return true;
888              }
889            }
890          }
891
892          return false;
893        } finally {
894          unlock();
895        }
896      }
897
898      V replace(K key, int hash, V newValue) {
899        Strategy<K, V, E> s = Impl.this.strategy;
900        lock();
901        try {
902          for (E e = getFirst(hash); e != null; e = s.getNext(e)) {
903            K entryKey = s.getKey(e);
904            if (s.getHash(e) == hash && entryKey != null
905                && s.equalKeys(key, entryKey)) {
906              // If the value disappeared, this entry is partially collected,
907              // and we should pretend like it doesn't exist.
908              V entryValue = s.getValue(e);
909              if (entryValue == null) {
910                return null;
911              }
912
913              s.setValue(e, newValue);
914              return entryValue;
915            }
916          }
917
918          return null;
919        } finally {
920          unlock();
921        }
922      }
923
924      V put(K key, int hash, V value, boolean onlyIfAbsent) {
925        Strategy<K, V, E> s = Impl.this.strategy;
926        lock();
927        try {
928          int count = this.count;
929          if (count++ > this.threshold) { // ensure capacity
930            expand();
931          }
932
933          AtomicReferenceArray<E> table = this.table;
934          int index = hash & (table.length() - 1);
935
936          E first = table.get(index);
937
938          // Look for an existing entry.
939          for (E e = first; e != null; e = s.getNext(e)) {
940            K entryKey = s.getKey(e);
941            if (s.getHash(e) == hash && entryKey != null
942                && s.equalKeys(key, entryKey)) {
943              // We found an existing entry.
944
945              // If the value disappeared, this entry is partially collected,
946              // and we should pretend like it doesn't exist.
947              V entryValue = s.getValue(e);
948              if (onlyIfAbsent && entryValue != null) {
949                return entryValue;
950              }
951
952              s.setValue(e, value);
953              return entryValue;
954            }
955          }
956
957          // Create a new entry.
958          ++modCount;
959          E newEntry = s.newEntry(key, hash, first);
960          s.setValue(newEntry, value);
961          table.set(index, newEntry);
962          this.count = count; // write-volatile
963          return null;
964        } finally {
965          unlock();
966        }
967      }
968
969      /**
970       * Expands the table if possible.
971       */
972      void expand() {
973        AtomicReferenceArray<E> oldTable = table;
974        int oldCapacity = oldTable.length();
975        if (oldCapacity >= MAXIMUM_CAPACITY) {
976          return;
977        }
978
979        /*
980         * Reclassify nodes in each list to new Map.  Because we are
981         * using power-of-two expansion, the elements from each bin
982         * must either stay at same index, or move with a power of two
983         * offset. We eliminate unnecessary node creation by catching
984         * cases where old nodes can be reused because their next
985         * fields won't change. Statistically, at the default
986         * threshold, only about one-sixth of them need cloning when
987         * a table doubles. The nodes they replace will be garbage
988         * collectable as soon as they are no longer referenced by any
989         * reader thread that may be in the midst of traversing table
990         * right now.
991         */
992
993        Strategy<K, V, E> s = Impl.this.strategy;
994        AtomicReferenceArray<E> newTable = newEntryArray(oldCapacity << 1);
995        threshold = newTable.length() * 3 / 4;
996        int newMask = newTable.length() - 1;
997        for (int oldIndex = 0; oldIndex < oldCapacity; oldIndex++) {
998          // We need to guarantee that any existing reads of old Map can
999          //  proceed. So we cannot yet null out each bin.
1000          E head = oldTable.get(oldIndex);
1001
1002          if (head != null) {
1003            E next = s.getNext(head);
1004            int headIndex = s.getHash(head) & newMask;
1005
1006            // Single node on list
1007            if (next == null) {
1008              newTable.set(headIndex, head);
1009            } else {
1010              // Reuse the consecutive sequence of nodes with the same target
1011              // index from the end of the list. tail points to the first
1012              // entry in the reusable list.
1013              E tail = head;
1014              int tailIndex = headIndex;
1015              for (E last = next; last != null; last = s.getNext(last)) {
1016                int newIndex = s.getHash(last) & newMask;
1017                if (newIndex != tailIndex) {
1018                  // The index changed. We'll need to copy the previous entry.
1019                  tailIndex = newIndex;
1020                  tail = last;
1021                }
1022              }
1023              newTable.set(tailIndex, tail);
1024
1025              // Clone nodes leading up to the tail.
1026              for (E e = head; e != tail; e = s.getNext(e)) {
1027                K key = s.getKey(e);
1028                if (key != null) {
1029                  int newIndex = s.getHash(e) & newMask;
1030                  E newNext = newTable.get(newIndex);
1031                  newTable.set(newIndex, s.copyEntry(key, e, newNext));
1032                } else {
1033                  // Key was reclaimed. Skip entry.
1034                }
1035              }
1036            }
1037          }
1038        }
1039        table = newTable;
1040      }
1041
1042      V remove(Object key, int hash) {
1043        Strategy<K, V, E> s = Impl.this.strategy;
1044        lock();
1045        try {
1046          int count = this.count - 1;
1047          AtomicReferenceArray<E> table = this.table;
1048          int index = hash & (table.length() - 1);
1049          E first = table.get(index);
1050
1051          for (E e = first; e != null; e = s.getNext(e)) {
1052            K entryKey = s.getKey(e);
1053            if (s.getHash(e) == hash && entryKey != null
1054                && s.equalKeys(entryKey, key)) {
1055              V entryValue = strategy.getValue(e);
1056              // All entries following removed node can stay
1057              // in list, but all preceding ones need to be
1058              // cloned.
1059              ++modCount;
1060              E newFirst = s.getNext(e);
1061              for (E p = first; p != e; p = s.getNext(p)) {
1062                K pKey = s.getKey(p);
1063                if (pKey != null) {
1064                  newFirst = s.copyEntry(pKey, p, newFirst);
1065                } else {
1066                  // Key was reclaimed. Skip entry.
1067                }
1068              }
1069              table.set(index, newFirst);
1070              this.count = count; // write-volatile
1071              return entryValue;
1072            }
1073          }
1074
1075          return null;
1076        } finally {
1077          unlock();
1078        }
1079      }
1080
1081      boolean remove(Object key, int hash, Object value) {
1082        Strategy<K, V, E> s = Impl.this.strategy;
1083        lock();
1084        try {
1085          int count = this.count - 1;
1086          AtomicReferenceArray<E> table = this.table;
1087          int index = hash & (table.length() - 1);
1088          E first = table.get(index);
1089
1090          for (E e = first; e != null; e = s.getNext(e)) {
1091            K entryKey = s.getKey(e);
1092            if (s.getHash(e) == hash && entryKey != null
1093                && s.equalKeys(entryKey, key)) {
1094              V entryValue = strategy.getValue(e);
1095              if (value == entryValue || (value != null && entryValue != null
1096                  && s.equalValues(entryValue, value))) {
1097                // All entries following removed node can stay
1098                // in list, but all preceding ones need to be
1099                // cloned.
1100                ++modCount;
1101                E newFirst = s.getNext(e);
1102                for (E p = first; p != e; p = s.getNext(p)) {
1103                  K pKey = s.getKey(p);
1104                  if (pKey != null) {
1105                    newFirst = s.copyEntry(pKey, p, newFirst);
1106                  } else {
1107                    // Key was reclaimed. Skip entry.
1108                  }
1109                }
1110                table.set(index, newFirst);
1111                this.count = count; // write-volatile
1112                return true;
1113              } else {
1114                return false;
1115              }
1116            }
1117          }
1118
1119          return false;
1120        } finally {
1121          unlock();
1122        }
1123      }
1124
1125      public boolean removeEntry(E entry, int hash, V value) {
1126        Strategy<K, V, E> s = Impl.this.strategy;
1127        lock();
1128        try {
1129          int count = this.count - 1;
1130          AtomicReferenceArray<E> table = this.table;
1131          int index = hash & (table.length() - 1);
1132          E first = table.get(index);
1133
1134          for (E e = first; e != null; e = s.getNext(e)) {
1135            if (s.getHash(e) == hash && entry.equals(e)) {
1136              V entryValue = s.getValue(e);
1137              if (entryValue == value || (value != null
1138                  && s.equalValues(entryValue, value))) {
1139                // All entries following removed node can stay
1140                // in list, but all preceding ones need to be
1141                // cloned.
1142                ++modCount;
1143                E newFirst = s.getNext(e);
1144                for (E p = first; p != e; p = s.getNext(p)) {
1145                  K pKey = s.getKey(p);
1146                  if (pKey != null) {
1147                    newFirst = s.copyEntry(pKey, p, newFirst);
1148                  } else {
1149                    // Key was reclaimed. Skip entry.
1150                  }
1151                }
1152                table.set(index, newFirst);
1153                this.count = count; // write-volatile
1154                return true;
1155              } else {
1156                return false;
1157              }
1158            }
1159          }
1160
1161          return false;
1162        } finally {
1163          unlock();
1164        }
1165      }
1166
1167      public boolean removeEntry(E entry, int hash) {
1168        Strategy<K, V, E> s = Impl.this.strategy;
1169        lock();
1170        try {
1171          int count = this.count - 1;
1172          AtomicReferenceArray<E> table = this.table;
1173          int index = hash & (table.length() - 1);
1174          E first = table.get(index);
1175
1176          for (E e = first; e != null; e = s.getNext(e)) {
1177            if (s.getHash(e) == hash && entry.equals(e)) {
1178              // All entries following removed node can stay
1179              // in list, but all preceding ones need to be
1180              // cloned.
1181              ++modCount;
1182              E newFirst = s.getNext(e);
1183              for (E p = first; p != e; p = s.getNext(p)) {
1184                K pKey = s.getKey(p);
1185                if (pKey != null) {
1186                  newFirst = s.copyEntry(pKey, p, newFirst);
1187                } else {
1188                  // Key was reclaimed. Skip entry.
1189                }
1190              }
1191              table.set(index, newFirst);
1192              this.count = count; // write-volatile
1193              return true;
1194            }
1195          }
1196
1197          return false;
1198        } finally {
1199          unlock();
1200        }
1201      }
1202
1203      void clear() {
1204        if (count != 0) {
1205          lock();
1206          try {
1207            AtomicReferenceArray<E> table = this.table;
1208            for (int i = 0; i < table.length(); i++) {
1209              table.set(i, null);
1210            }
1211            ++modCount;
1212            count = 0; // write-volatile
1213          } finally {
1214            unlock();
1215          }
1216        }
1217      }
1218    }
1219
1220    /* ---------------- Public operations -------------- */
1221
1222    /**
1223     * Returns {@code true} if this map contains no key-value mappings.
1224     *
1225     * @return {@code true} if this map contains no key-value mappings
1226     */
1227    @Override public boolean isEmpty() {
1228      final Segment[] segments = this.segments;
1229      /*
1230       * We keep track of per-segment modCounts to avoid ABA
1231       * problems in which an element in one segment was added and
1232       * in another removed during traversal, in which case the
1233       * table was never actually empty at any point. Note the
1234       * similar use of modCounts in the size() and containsValue()
1235       * methods, which are the only other methods also susceptible
1236       * to ABA problems.
1237       */
1238      int[] mc = new int[segments.length];
1239      int mcsum = 0;
1240      for (int i = 0; i < segments.length; ++i) {
1241        if (segments[i].count != 0) {
1242          return false;
1243        } else {
1244          mcsum += mc[i] = segments[i].modCount;
1245        }
1246      }
1247      // If mcsum happens to be zero, then we know we got a snapshot
1248      // before any modifications at all were made.  This is
1249      // probably common enough to bother tracking.
1250      if (mcsum != 0) {
1251        for (int i = 0; i < segments.length; ++i) {
1252          if (segments[i].count != 0 ||
1253              mc[i] != segments[i].modCount) {
1254            return false;
1255          }
1256        }
1257      }
1258      return true;
1259    }
1260
1261    /**
1262     * Returns the number of key-value mappings in this map.  If the map
1263     * contains more than {@code Integer.MAX_VALUE} elements, returns
1264     * {@code Integer.MAX_VALUE}.
1265     *
1266     * @return the number of key-value mappings in this map
1267     */
1268    @Override public int size() {
1269      final Segment[] segments = this.segments;
1270      long sum = 0;
1271      long check = 0;
1272      int[] mc = new int[segments.length];
1273      // Try a few times to get accurate count. On failure due to
1274      // continuous async changes in table, resort to locking.
1275      for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
1276        check = 0;
1277        sum = 0;
1278        int mcsum = 0;
1279        for (int i = 0; i < segments.length; ++i) {
1280          sum += segments[i].count;
1281          mcsum += mc[i] = segments[i].modCount;
1282        }
1283        if (mcsum != 0) {
1284          for (int i = 0; i < segments.length; ++i) {
1285            check += segments[i].count;
1286            if (mc[i] != segments[i].modCount) {
1287              check = -1; // force retry
1288              break;
1289            }
1290          }
1291        }
1292        if (check == sum) {
1293          break;
1294        }
1295      }
1296      if (check != sum) { // Resort to locking all segments
1297        sum = 0;
1298        for (Segment segment : segments) {
1299          segment.lock();
1300        }
1301        for (Segment segment : segments) {
1302          sum += segment.count;
1303        }
1304        for (Segment segment : segments) {
1305          segment.unlock();
1306        }
1307      }
1308      if (sum > Integer.MAX_VALUE) {
1309        return Integer.MAX_VALUE;
1310      } else {
1311        return (int) sum;
1312      }
1313    }
1314
1315    /**
1316     * Returns the value to which the specified key is mapped, or {@code null}
1317     * if this map contains no mapping for the key.
1318     *
1319     * <p>More formally, if this map contains a mapping from a key {@code k} to
1320     * a value {@code v} such that {@code key.equals(k)}, then this method
1321     * returns {@code v}; otherwise it returns {@code null}.  (There can be at
1322     * most one such mapping.)
1323     *
1324     * @throws NullPointerException if the specified key is null
1325     */
1326    @Override public V get(Object key) {
1327      if (key == null) {
1328        throw new NullPointerException("key");
1329      }
1330      int hash = hash(key);
1331      return segmentFor(hash).get(key, hash);
1332    }
1333
1334    /**
1335     * Tests if the specified object is a key in this table.
1336     *
1337     * @param key possible key
1338     * @return {@code true} if and only if the specified object is a key in
1339     *         this table, as determined by the {@code equals} method;
1340     *         {@code false} otherwise.
1341     * @throws NullPointerException if the specified key is null
1342     */
1343    @Override public boolean containsKey(Object key) {
1344      if (key == null) {
1345        throw new NullPointerException("key");
1346      }
1347      int hash = hash(key);
1348      return segmentFor(hash).containsKey(key, hash);
1349    }
1350
1351    /**
1352     * Returns {@code true} if this map maps one or more keys to the specified
1353     * value. Note: This method requires a full internal traversal of the hash
1354     * table, and so is much slower than method {@code containsKey}.
1355     *
1356     * @param value value whose presence in this map is to be tested
1357     * @return {@code true} if this map maps one or more keys to the specified
1358     *         value
1359     * @throws NullPointerException if the specified value is null
1360     */
1361    @Override public boolean containsValue(Object value) {
1362      if (value == null) {
1363        throw new NullPointerException("value");
1364      }
1365
1366      // See explanation of modCount use above
1367
1368      final Segment[] segments = this.segments;
1369      int[] mc = new int[segments.length];
1370
1371      // Try a few times without locking
1372      for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {
1373        int mcsum = 0;
1374        for (int i = 0; i < segments.length; ++i) {
1375          @SuppressWarnings("UnusedDeclaration")
1376          int c = segments[i].count;
1377          mcsum += mc[i] = segments[i].modCount;
1378          if (segments[i].containsValue(value)) {
1379            return true;
1380          }
1381        }
1382        boolean cleanSweep = true;
1383        if (mcsum != 0) {
1384          for (int i = 0; i < segments.length; ++i) {
1385            @SuppressWarnings("UnusedDeclaration")
1386            int c = segments[i].count;
1387            if (mc[i] != segments[i].modCount) {
1388              cleanSweep = false;
1389              break;
1390            }
1391          }
1392        }
1393        if (cleanSweep) {
1394          return false;
1395        }
1396      }
1397      // Resort to locking all segments
1398      for (Segment segment : segments) {
1399        segment.lock();
1400      }
1401      boolean found = false;
1402      try {
1403        for (Segment segment : segments) {
1404          if (segment.containsValue(value)) {
1405            found = true;
1406            break;
1407          }
1408        }
1409      } finally {
1410        for (Segment segment : segments) {
1411          segment.unlock();
1412        }
1413      }
1414      return found;
1415    }
1416
1417    /**
1418     * Maps the specified key to the specified value in this table. Neither the
1419     * key nor the value can be null.
1420     *
1421     * <p> The value can be retrieved by calling the {@code get} method with a
1422     * key that is equal to the original key.
1423     *
1424     * @param key   key with which the specified value is to be associated
1425     * @param value value to be associated with the specified key
1426     * @return the previous value associated with {@code key}, or {@code null}
1427     *         if there was no mapping for {@code key}
1428     * @throws NullPointerException if the specified key or value is null
1429     */
1430    @Override public V put(K key, V value) {
1431      if (key == null) {
1432        throw new NullPointerException("key");
1433      }
1434      if (value == null) {
1435        throw new NullPointerException("value");
1436      }
1437      int hash = hash(key);
1438      return segmentFor(hash).put(key, hash, value, false);
1439    }
1440
1441    /**
1442     * {@inheritDoc}
1443     *
1444     * @return the previous value associated with the specified key, or
1445     *         {@code null} if there was no mapping for the key
1446     * @throws NullPointerException if the specified key or value is null
1447     */
1448    public V putIfAbsent(K key, V value) {
1449      if (key == null) {
1450        throw new NullPointerException("key");
1451      }
1452      if (value == null) {
1453        throw new NullPointerException("value");
1454      }
1455      int hash = hash(key);
1456      return segmentFor(hash).put(key, hash, value, true);
1457    }
1458
1459    /**
1460     * Copies all of the mappings from the specified map to this one. These
1461     * mappings replace any mappings that this map had for any of the keys
1462     * currently in the specified map.
1463     *
1464     * @param m mappings to be stored in this map
1465     */
1466    @Override public void putAll(Map<? extends K, ? extends V> m) {
1467      for (Entry<? extends K, ? extends V> e : m.entrySet()) {
1468        put(e.getKey(), e.getValue());
1469      }
1470    }
1471
1472    /**
1473     * Removes the key (and its corresponding value) from this map. This method
1474     * does nothing if the key is not in the map.
1475     *
1476     * @param key the key that needs to be removed
1477     * @return the previous value associated with {@code key}, or {@code null}
1478     *         if there was no mapping for {@code key}
1479     * @throws NullPointerException if the specified key is null
1480     */
1481    @Override public V remove(Object key) {
1482      if (key == null) {
1483        throw new NullPointerException("key");
1484      }
1485      int hash = hash(key);
1486      return segmentFor(hash).remove(key, hash);
1487    }
1488
1489    /**
1490     * {@inheritDoc}
1491     *
1492     * @throws NullPointerException if the specified key is null
1493     */
1494    public boolean remove(Object key, Object value) {
1495      if (key == null) {
1496        throw new NullPointerException("key");
1497      }
1498      int hash = hash(key);
1499      return segmentFor(hash).remove(key, hash, value);
1500    }
1501
1502    /**
1503     * {@inheritDoc}
1504     *
1505     * @throws NullPointerException if any of the arguments are null
1506     */
1507    public boolean replace(K key, V oldValue, V newValue) {
1508      if (key == null) {
1509        throw new NullPointerException("key");
1510      }
1511      if (oldValue == null) {
1512        throw new NullPointerException("oldValue");
1513      }
1514      if (newValue == null) {
1515        throw new NullPointerException("newValue");
1516      }
1517      int hash = hash(key);
1518      return segmentFor(hash).replace(key, hash, oldValue, newValue);
1519    }
1520
1521    /**
1522     * {@inheritDoc}
1523     *
1524     * @return the previous value associated with the specified key, or
1525     *         {@code null} if there was no mapping for the key
1526     * @throws NullPointerException if the specified key or value is null
1527     */
1528    public V replace(K key, V value) {
1529      if (key == null) {
1530        throw new NullPointerException("key");
1531      }
1532      if (value == null) {
1533        throw new NullPointerException("value");
1534      }
1535      int hash = hash(key);
1536      return segmentFor(hash).replace(key, hash, value);
1537    }
1538
1539    /**
1540     * Removes all of the mappings from this map.
1541     */
1542    @Override public void clear() {
1543      for (Segment segment : segments) {
1544        segment.clear();
1545      }
1546    }
1547
1548    Set<K> keySet;
1549
1550    /**
1551     * Returns a {@link java.util.Set} view of the keys contained in this map.
1552     * The set is backed by the map, so changes to the map are reflected in the
1553     * set, and vice-versa. The set supports element removal, which removes the
1554     * corresponding mapping from this map, via the {@code Iterator.remove},
1555     * {@code Set.remove}, {@code removeAll}, {@code retainAll}, and
1556     * {@code clear} operations. It does not support the {@code add} or
1557     * {@code addAll} operations.
1558     *
1559     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
1560     * will never throw {@link java.util.ConcurrentModificationException}, and
1561     * guarantees to traverse elements as they existed upon construction of the
1562     * iterator, and may (but is not guaranteed to) reflect any modifications
1563     * subsequent to construction.
1564     */
1565    @Override public Set<K> keySet() {
1566      Set<K> ks = keySet;
1567      return (ks != null) ? ks : (keySet = new KeySet());
1568    }
1569
1570    Collection<V> values;
1571
1572    /**
1573     * Returns a {@link java.util.Collection} view of the values contained in
1574     * this map. The collection is backed by the map, so changes to the map are
1575     * reflected in the collection, and vice-versa. The collection supports
1576     * element removal, which removes the corresponding mapping from this map,
1577     * via the {@code Iterator.remove}, {@code Collection.remove},
1578     * {@code removeAll}, {@code retainAll}, and {@code clear} operations. It
1579     * does not support the {@code add} or {@code addAll} operations.
1580     *
1581     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
1582     * will never throw {@link java.util.ConcurrentModificationException}, and
1583     * guarantees to traverse elements as they existed upon construction of the
1584     * iterator, and may (but is not guaranteed to) reflect any modifications
1585     * subsequent to construction.
1586     */
1587    @Override public Collection<V> values() {
1588      Collection<V> vs = values;
1589      return (vs != null) ? vs : (values = new Values());
1590    }
1591
1592    Set<Entry<K, V>> entrySet;
1593
1594    /**
1595     * Returns a {@link java.util.Set} view of the mappings contained in this
1596     * map. The set is backed by the map, so changes to the map are reflected in
1597     * the set, and vice-versa. The set supports element removal, which removes
1598     * the corresponding mapping from the map, via the {@code Iterator.remove},
1599     * {@code Set.remove}, {@code removeAll}, {@code retainAll}, and
1600     * {@code clear} operations. It does not support the {@code add} or
1601     * {@code addAll} operations.
1602     *
1603     * <p>The view's {@code iterator} is a "weakly consistent" iterator that
1604     * will never throw {@link java.util.ConcurrentModificationException}, and
1605     * guarantees to traverse elements as they existed upon construction of the
1606     * iterator, and may (but is not guaranteed to) reflect any modifications
1607     * subsequent to construction.
1608     */
1609    @Override public Set<Entry<K, V>> entrySet() {
1610      Set<Entry<K, V>> es = entrySet;
1611      return (es != null) ? es : (entrySet = new EntrySet());
1612    }
1613
1614    /* ---------------- Iterator Support -------------- */
1615
1616    abstract class HashIterator {
1617
1618      int nextSegmentIndex;
1619      int nextTableIndex;
1620      AtomicReferenceArray<E> currentTable;
1621      E nextEntry;
1622      WriteThroughEntry nextExternal;
1623      WriteThroughEntry lastReturned;
1624
1625      HashIterator() {
1626        nextSegmentIndex = segments.length - 1;
1627        nextTableIndex = -1;
1628        advance();
1629      }
1630
1631      public boolean hasMoreElements() {
1632        return hasNext();
1633      }
1634
1635      final void advance() {
1636        nextExternal = null;
1637
1638        if (nextInChain()) {
1639          return;
1640        }
1641
1642        if (nextInTable()) {
1643          return;
1644        }
1645
1646        while (nextSegmentIndex >= 0) {
1647          Segment seg = segments[nextSegmentIndex--];
1648          if (seg.count != 0) {
1649            currentTable = seg.table;
1650            nextTableIndex = currentTable.length() - 1;
1651            if (nextInTable()) {
1652              return;
1653            }
1654          }
1655        }
1656      }
1657
1658      /**
1659       * Finds the next entry in the current chain. Returns true if an entry
1660       * was found.
1661       */
1662      boolean nextInChain() {
1663        Strategy<K, V, E> s = Impl.this.strategy;
1664        if (nextEntry != null) {
1665          for (nextEntry = s.getNext(nextEntry); nextEntry != null;
1666              nextEntry = s.getNext(nextEntry)) {
1667            if (advanceTo(nextEntry)) {
1668              return true;
1669            }
1670          }
1671        }
1672        return false;
1673      }
1674
1675      /**
1676       * Finds the next entry in the current table. Returns true if an entry
1677       * was found.
1678       */
1679      boolean nextInTable() {
1680        while (nextTableIndex >= 0) {
1681          if ((nextEntry = currentTable.get(nextTableIndex--)) != null) {
1682            if (advanceTo(nextEntry) || nextInChain()) {
1683              return true;
1684            }
1685          }
1686        }
1687        return false;
1688      }
1689
1690      /**
1691       * Advances to the given entry. Returns true if the entry was valid,
1692       * false if it should be skipped.
1693       */
1694      boolean advanceTo(E entry) {
1695        Strategy<K, V, E> s = Impl.this.strategy;
1696        K key = s.getKey(entry);
1697        V value = s.getValue(entry);
1698        if (key != null && value != null) {
1699          nextExternal = new WriteThroughEntry(key, value);
1700          return true;
1701        } else {
1702          // Skip partially reclaimed entry.
1703          return false;
1704        }
1705      }
1706
1707      public boolean hasNext() {
1708        return nextExternal != null;
1709      }
1710
1711      WriteThroughEntry nextEntry() {
1712        if (nextExternal == null) {
1713          throw new NoSuchElementException();
1714        }
1715        lastReturned = nextExternal;
1716        advance();
1717        return lastReturned;
1718      }
1719
1720      public void remove() {
1721        if (lastReturned == null) {
1722          throw new IllegalStateException();
1723        }
1724        Impl.this.remove(lastReturned.getKey());
1725        lastReturned = null;
1726      }
1727    }
1728
1729    final class KeyIterator extends HashIterator implements Iterator<K> {
1730
1731      public K next() {
1732        return super.nextEntry().getKey();
1733      }
1734    }
1735
1736    final class ValueIterator extends HashIterator implements Iterator<V> {
1737
1738      public V next() {
1739        return super.nextEntry().getValue();
1740      }
1741    }
1742
1743    /**
1744     * Custom Entry class used by EntryIterator.next(), that relays setValue
1745     * changes to the underlying map.
1746     */
1747    final class WriteThroughEntry extends AbstractMapEntry<K, V> {
1748      final K key;
1749      V value;
1750
1751      WriteThroughEntry(K key, V value) {
1752        this.key = key;
1753        this.value = value;
1754      }
1755
1756      @Override public K getKey() {
1757        return key;
1758      }
1759
1760      @Override public V getValue() {
1761        return value;
1762      }
1763
1764      /**
1765       * Set our entry's value and write through to the map. The value to
1766       * return is somewhat arbitrary here. Since a WriteThroughEntry does not
1767       * necessarily track asynchronous changes, the most recent "previous"
1768       * value could be different from what we return (or could even have been
1769       * removed in which case the put will re-establish). We do not and
1770       * cannot guarantee more.
1771       */
1772      @Override public V setValue(V value) {
1773        if (value == null) {
1774          throw new NullPointerException();
1775        }
1776        V oldValue = Impl.this.put(getKey(), value);
1777        this.value = value;
1778        return oldValue;
1779      }
1780    }
1781
1782    final class EntryIterator extends HashIterator
1783        implements Iterator<Entry<K, V>> {
1784
1785      public Entry<K, V> next() {
1786        return nextEntry();
1787      }
1788    }
1789
1790    final class KeySet extends AbstractSet<K> {
1791
1792      @Override public Iterator<K> iterator() {
1793        return new KeyIterator();
1794      }
1795
1796      @Override public int size() {
1797        return Impl.this.size();
1798      }
1799
1800      @Override public boolean isEmpty() {
1801        return Impl.this.isEmpty();
1802      }
1803
1804      @Override public boolean contains(Object o) {
1805        return Impl.this.containsKey(o);
1806      }
1807
1808      @Override public boolean remove(Object o) {
1809        return Impl.this.remove(o) != null;
1810      }
1811
1812      @Override public void clear() {
1813        Impl.this.clear();
1814      }
1815    }
1816
1817    final class Values extends AbstractCollection<V> {
1818
1819      @Override public Iterator<V> iterator() {
1820        return new ValueIterator();
1821      }
1822
1823      @Override public int size() {
1824        return Impl.this.size();
1825      }
1826
1827      @Override public boolean isEmpty() {
1828        return Impl.this.isEmpty();
1829      }
1830
1831      @Override public boolean contains(Object o) {
1832        return Impl.this.containsValue(o);
1833      }
1834
1835      @Override public void clear() {
1836        Impl.this.clear();
1837      }
1838    }
1839
1840    final class EntrySet extends AbstractSet<Entry<K, V>> {
1841
1842      @Override public Iterator<Entry<K, V>> iterator() {
1843        return new EntryIterator();
1844      }
1845
1846      @Override public boolean contains(Object o) {
1847        if (!(o instanceof Entry)) {
1848          return false;
1849        }
1850        Entry<?, ?> e = (Entry<?, ?>) o;
1851        Object key = e.getKey();
1852        if (key == null) {
1853          return false;
1854        }
1855        V v = Impl.this.get(key);
1856
1857        return v != null && strategy.equalValues(v, e.getValue());
1858      }
1859
1860      @Override public boolean remove(Object o) {
1861        if (!(o instanceof Entry)) {
1862          return false;
1863        }
1864        Entry<?, ?> e = (Entry<?, ?>) o;
1865        Object key = e.getKey();
1866        return key != null && Impl.this.remove(key, e.getValue());
1867      }
1868
1869      @Override public int size() {
1870        return Impl.this.size();
1871      }
1872
1873      @Override public boolean isEmpty() {
1874        return Impl.this.isEmpty();
1875      }
1876
1877      @Override public void clear() {
1878        Impl.this.clear();
1879      }
1880    }
1881
1882    /* ---------------- Serialization Support -------------- */
1883
1884    private static final long serialVersionUID = 1;
1885
1886    private void writeObject(java.io.ObjectOutputStream out)
1887        throws IOException {
1888      out.writeInt(size());
1889      out.writeInt(segments.length); // concurrencyLevel
1890      out.writeObject(strategy);
1891      for (Entry<K, V> entry : entrySet()) {
1892        out.writeObject(entry.getKey());
1893        out.writeObject(entry.getValue());
1894      }
1895      out.writeObject(null); // terminate entries
1896    }
1897
1898    /**
1899     * Fields used during deserialization. We use a nested class so we don't
1900     * load them until we need them. We need to use reflection to set final
1901     * fields outside of the constructor.
1902     */
1903    static class Fields {
1904
1905      static final Field segmentShift = findField("segmentShift");
1906      static final Field segmentMask = findField("segmentMask");
1907      static final Field segments = findField("segments");
1908      static final Field strategy = findField("strategy");
1909
1910      static Field findField(String name) {
1911        try {
1912          Field f = Impl.class.getDeclaredField(name);
1913          f.setAccessible(true);
1914          return f;
1915        } catch (NoSuchFieldException e) {
1916          throw new AssertionError(e);
1917        }
1918      }
1919    }
1920
1921    @SuppressWarnings("unchecked")
1922    private void readObject(java.io.ObjectInputStream in)
1923        throws IOException, ClassNotFoundException {
1924      try {
1925        int initialCapacity = in.readInt();
1926        int concurrencyLevel = in.readInt();
1927        Strategy<K, V, E> strategy = (Strategy<K, V, E>) in.readObject();
1928
1929        if (concurrencyLevel > MAX_SEGMENTS) {
1930          concurrencyLevel = MAX_SEGMENTS;
1931        }
1932
1933        // Find power-of-two sizes best matching arguments
1934        int segmentShift = 0;
1935        int segmentCount = 1;
1936        while (segmentCount < concurrencyLevel) {
1937          ++segmentShift;
1938          segmentCount <<= 1;
1939        }
1940        Fields.segmentShift.set(this, 32 - segmentShift);
1941        Fields.segmentMask.set(this, segmentCount - 1);
1942        Fields.segments.set(this, newSegmentArray(segmentCount));
1943
1944        if (initialCapacity > MAXIMUM_CAPACITY) {
1945          initialCapacity = MAXIMUM_CAPACITY;
1946        }
1947
1948        int segmentCapacity = initialCapacity / segmentCount;
1949        if (segmentCapacity * segmentCount < initialCapacity) {
1950          ++segmentCapacity;
1951        }
1952
1953        int segmentSize = 1;
1954        while (segmentSize < segmentCapacity) {
1955            segmentSize <<= 1;
1956        }
1957        for (int i = 0; i < this.segments.length; ++i) {
1958          this.segments[i] = new Segment(segmentSize);
1959        }
1960
1961        Fields.strategy.set(this, strategy);
1962
1963        while (true) {
1964          K key = (K) in.readObject();
1965          if (key == null) {
1966            break; // terminator
1967          }
1968          V value = (V) in.readObject();
1969          put(key, value);
1970        }
1971      } catch (IllegalAccessException e) {
1972        throw new AssertionError(e);
1973      }
1974    }
1975  }
1976
1977  static class ComputingImpl<K, V, E> extends Impl<K, V, E> {
1978
1979    static final long serialVersionUID = 0;
1980
1981    final ComputingStrategy<K, V, E> computingStrategy;
1982    final Function<? super K, ? extends V> computer;
1983
1984    /**
1985     * Creates a new, empty map with the specified strategy, initial capacity,
1986     * load factor and concurrency level.
1987     */
1988    ComputingImpl(ComputingStrategy<K, V, E> strategy, Builder builder,
1989        Function<? super K, ? extends V> computer) {
1990      super(strategy, builder);
1991      this.computingStrategy = strategy;
1992      this.computer = computer;
1993    }
1994
1995    @Override public V get(Object k) {
1996      /*
1997       * This cast isn't safe, but we can rely on the fact that K is almost
1998       * always passed to Map.get(), and tools like IDEs and Findbugs can
1999       * catch situations where this isn't the case.
2000       *
2001       * The alternative is to add an overloaded method, but the chances of
2002       * a user calling get() instead of the new API and the risks inherent
2003       * in adding a new API outweigh this little hole.
2004       */
2005      @SuppressWarnings("unchecked")
2006      K key = (K) k;
2007
2008      if (key == null) {
2009        throw new NullPointerException("key");
2010      }
2011
2012      int hash = hash(key);
2013      Segment segment = segmentFor(hash);
2014      outer: while (true) {
2015        E entry = segment.getEntry(key, hash);
2016        if (entry == null) {
2017          boolean created = false;
2018          segment.lock();
2019          try {
2020            // Try again--an entry could have materialized in the interim.
2021            entry = segment.getEntry(key, hash);
2022            if (entry == null) {
2023              // Create a new entry.
2024              created = true;
2025              int count = segment.count;
2026              if (count++ > segment.threshold) { // ensure capacity
2027                segment.expand();
2028              }
2029              AtomicReferenceArray<E> table = segment.table;
2030              int index = hash & (table.length() - 1);
2031              E first = table.get(index);
2032              ++segment.modCount;
2033              entry = computingStrategy.newEntry(key, hash, first);
2034              table.set(index, entry);
2035              segment.count = count; // write-volatile
2036            }
2037          } finally {
2038            segment.unlock();
2039          }
2040
2041          if (created) {
2042            // This thread solely created the entry.
2043            boolean success = false;
2044            try {
2045              V value = computingStrategy.compute(key, entry, computer);
2046              if (value == null) {
2047                throw new NullPointerException(
2048                    "compute() returned null unexpectedly");
2049              }
2050              success = true;
2051              return value;
2052            } finally {
2053              if (!success) {
2054                segment.removeEntry(entry, hash);
2055              }
2056            }
2057          }
2058        }
2059
2060        // The entry already exists. Wait for the computation.
2061        boolean interrupted = false;
2062        try {
2063          while (true) {
2064            try {
2065              V value = computingStrategy.waitForValue(entry);
2066              if (value == null) {
2067                // Purge entry and try again.
2068                segment.removeEntry(entry, hash);
2069                continue outer;
2070              }
2071              return value;
2072            } catch (InterruptedException e) {
2073              interrupted = true;
2074            }
2075          }
2076        } finally {
2077          if (interrupted) {
2078            Thread.currentThread().interrupt();
2079          }
2080        }
2081      }
2082    }
2083  }
2084
2085  /**
2086   * A basic, no-frills implementation of {@code Strategy} using {@link
2087   * SimpleInternalEntry}. Intended to be subclassed to provide customized
2088   * behavior. For example, the following creates a map that uses byte arrays as
2089   * keys: <pre>   {@code
2090   *
2091   *   return new CustomConcurrentHashMap.Builder().buildMap(
2092   *       new SimpleStrategy<byte[], V>() {
2093   *         public int hashKey(Object key) {
2094   *           return Arrays.hashCode((byte[]) key);
2095   *         }
2096   *         public boolean equalKeys(byte[] a, Object b) {
2097   *           return Arrays.equals(a, (byte[]) b);
2098   *         }
2099   *       });}</pre>
2100   *
2101   * With nothing overridden, it yields map behavior equivalent to that of
2102   * {@link ConcurrentHashMap}.
2103   */
2104  static class SimpleStrategy<K, V>
2105      implements Strategy<K, V, SimpleInternalEntry<K, V>> {
2106    public SimpleInternalEntry<K, V> newEntry(
2107        K key, int hash, SimpleInternalEntry<K, V> next) {
2108      return new SimpleInternalEntry<K, V>(key, hash, null, next);
2109    }
2110    public SimpleInternalEntry<K, V> copyEntry(K key,
2111        SimpleInternalEntry<K, V> original, SimpleInternalEntry<K, V> next) {
2112      return new SimpleInternalEntry<K, V>(
2113          key, original.hash, original.value, next);
2114    }
2115    public void setValue(SimpleInternalEntry<K, V> entry, V value) {
2116      entry.value = value;
2117    }
2118    public V getValue(SimpleInternalEntry<K, V> entry) {
2119      return entry.value;
2120    }
2121    public boolean equalKeys(K a, Object b) {
2122      return a.equals(b);
2123    }
2124    public boolean equalValues(V a, Object b) {
2125      return a.equals(b);
2126    }
2127    public int hashKey(Object key) {
2128      return key.hashCode();
2129    }
2130    public K getKey(SimpleInternalEntry<K, V> entry) {
2131      return entry.key;
2132    }
2133    public SimpleInternalEntry<K, V> getNext(SimpleInternalEntry<K, V> entry) {
2134      return entry.next;
2135    }
2136    public int getHash(SimpleInternalEntry<K, V> entry) {
2137      return entry.hash;
2138    }
2139    public void setInternals(
2140        Internals<K, V, SimpleInternalEntry<K, V>> internals) {
2141      // ignore?
2142    }
2143  }
2144
2145  /**
2146   * A basic, no-frills entry class used by {@link SimpleInternalEntry}.
2147   */
2148  static class SimpleInternalEntry<K, V> {
2149    final K key;
2150    final int hash;
2151    final SimpleInternalEntry<K, V> next;
2152    volatile V value;
2153    SimpleInternalEntry(
2154        K key, int hash, @Nullable V value, SimpleInternalEntry<K, V> next) {
2155      this.key = key;
2156      this.hash = hash;
2157      this.value = value;
2158      this.next = next;
2159    }
2160  }
2161}
2162