ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/CustomConcurrentHashMap.java
(Generate patch)

Comparing jsr166/src/extra166y/CustomConcurrentHashMap.java (file contents):
Revision 1.2 by dl, Tue Jun 30 14:56:53 2009 UTC vs.
Revision 1.37 by jsr166, Sun Sep 13 16:28:13 2015 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < * http://creativecommons.org/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7   package extra166y;
8 +
9   import java.lang.ref.*;
10   import java.lang.reflect.*;
11   import java.io.*;
# Line 19 | Line 20 | import sun.misc.Unsafe;
20   * user-supplied computational methods for setting and updating
21   * values. In particular: <ul>
22   *
23 < *   <li> Identity-based, Equality-based or User-definable {@link
24 < *        Equivalence}-based comparisons controlling membership.
23 > *   <li>Identity-based, Equality-based or User-definable {@link
24 > *       Equivalence}-based comparisons controlling membership.
25   *
26 < *   <li> {@linkplain SoftReference Soft}, {@linkplain
27 < *        WeakReference weak} or strong (regular) keys and values.
26 > *   <li>{@linkplain SoftReference Soft}, {@linkplain
27 > *       WeakReference weak} or strong (regular) keys and values.
28   *
29 < *   <li> User-definable <code>MappingFunctions</code> that may be
30 < *        used in method {@link
31 < *        CustomConcurrentHashMap#computeIfAbsent} to atomically
32 < *        establish a computed value, along with
33 < *        <code>RemappingFunctions</code> that can be used in method
34 < *        {@link CustomConcurrentHashMap#compute} to atomically
35 < *        replace values.
29 > *   <li>User-definable {@code MappingFunctions} that may be
30 > *       used in method {@link
31 > *       CustomConcurrentHashMap#computeIfAbsent} to atomically
32 > *       establish a computed value, along with
33 > *       {@code RemappingFunctions} that can be used in method
34 > *       {@link CustomConcurrentHashMap#compute} to atomically
35 > *       replace values.
36   *
37 < *    <li>Factory methods returning specialized forms for <tt>int</tt>
38 < *        keys and/or values, that may be more space-efficient
37 > *   <li>Factory methods returning specialized forms for {@code int}
38 > *       keys and/or values, that may be more space-efficient
39   *
40   * </ul>
41 < *
41 > *
42   * Per-map settings are established in constructors, as in the
43   * following usages (that assume static imports to simplify expression
44   * of configuration parameters):
45 < *
45 > *
46   * <pre>
47   * {@code
48   * identityMap = new CustomConcurrentHashMap<Person,Salary>
# Line 53 | Line 54 | import sun.misc.Unsafe;
54   *     (STRONG,
55   *      new Equivalence<Person>() {
56   *          public boolean equal(Person k, Object x) {
57 < *            return x instanceOf Person && k.name.equals(((Person)x).name);
57 > *            return x instanceof Person && k.name.equals(((Person)x).name);
58   *          }
59 < *          public int hash(Object x) {
60 < *             return (x instanceOf Person)? ((Person)x).name.hashCode() : 0;
59 > *          public int hash(Object x) {
60 > *             return (x instanceof Person) ? ((Person)x).name.hashCode() : 0;
61   *          }
62   *        },
63   *      STRONG, EQUALS, 0);
# Line 69 | Line 70 | import sun.misc.Unsafe;
70   * and identity-based equality for keys. The third usage
71   * illustrates a map with a custom Equivalence that looks only at the
72   * name field of a (fictional) Person class.
73 < *
73 > *
74   * <p>This class also includes nested class {@link KeySet}
75   * that provides space-efficient Set views of maps, also supporting
76 < * method <code>intern</code>, which may be of use in canonicalizing
76 > * method {@code intern}, which may be of use in canonicalizing
77   * elements.
78   *
79   * <p>When used with (Weak or Soft) Reference keys and/or values,
80 < * elements that have asynchronously become <code>null</code> are
80 > * elements that have asynchronously become {@code null} are
81   * treated as absent from the map and (eventually) removed from maps
82   * via a background thread common across all maps. Because of the
83   * potential for asynchronous clearing of References, methods such as
84 < * <code>containsValue</code> have weaker guarantees than you might
85 < * expect even in the absence of other explicity concurrent
86 < * operations. For example <code>containsValue(value)</code> may
87 < * return true even if <code>value</code> is no longer available upon
84 > * {@code containsValue} have weaker guarantees than you might
85 > * expect even in the absence of other explicitly concurrent
86 > * operations. For example {@code containsValue(value)} may
87 > * return true even if {@code value} is no longer available upon
88   * return from the method.
89   *
90   * <p>When Equivalences other than equality are used, the returned
91 < * collections may violate the specifications of <tt>Map</tt> and/or
92 < * <tt>Set</tt> interfaces, which mandate the use of the
93 < * <tt>equals</tt> method when comparing objects.  The methods of this
91 > * collections may violate the specifications of {@code Map} and/or
92 > * {@code Set} interfaces, which mandate the use of the
93 > * {@code equals} method when comparing objects.  The methods of this
94   * class otherwise have properties similar to those of {@link
95   * java.util.ConcurrentHashMap} under its default settings.  To
96   * adaptively maintain semantics and performance under varying
# Line 110 | Line 111 | import sun.misc.Unsafe;
111   * @param <K> the type of keys maintained by this map
112   * @param <V> the type of mapped values
113   */
114 < public class CustomConcurrentHashMap<K, V> extends AbstractMap<K, V>
115 <    implements ConcurrentMap<K, V>, Serializable {
114 > public class CustomConcurrentHashMap<K,V> extends AbstractMap<K,V>
115 >    implements ConcurrentMap<K,V>, Serializable {
116      private static final long serialVersionUID = 7249069246764182397L;
117  
118      /*
# Line 126 | Line 127 | public class CustomConcurrentHashMap<K,
127       * Additionally, because Reference keys/values may become null
128       * asynchronously, we cannot ensure snapshot integrity in methods
129       * such as containsValue, so do not try to obtain them (so, no
130 <     * modCounts etc).
130 >     * modCounts etc).
131       *
132       * Also, the volatility of Segment count vs table fields are
133       * swapped, enabled by ensuring fences on new node assignments.
# Line 138 | Line 139 | public class CustomConcurrentHashMap<K,
139       * maps. strong denotes ordinary objects. weak and soft denote the
140       * corresponding {@link java.lang.ref.Reference} types.
141       */
142 <    public enum Strength {
142 >    public enum Strength {
143          strong("Strong"), weak("Weak"), soft("Soft");
144          private final String name;
145          Strength(String name) { this.name = name; }
146          String getName() { return name; }
147      };
148  
149 <    
149 >
150      /** The strength of ordinary references */
151      public static final Strength STRONG = Strength.strong;
152  
# Line 165 | Line 166 | public class CustomConcurrentHashMap<K,
166       * An object performing equality comparisons, along with a hash
167       * function consistent with this comparison.  The type signatures
168       * of the methods of this interface reflect those of {@link
169 <     * java.util.Map}: While only elements of <code>K</code> may be
170 <     * entered into a Map, any <code>Object</code> may be tested for
169 >     * java.util.Map}: While only elements of {@code K} may be
170 >     * entered into a Map, any {@code Object} may be tested for
171       * membership. Note that the performance of hash maps is heavily
172       * dependent on the quality of hash functions.
173       */
# Line 184 | Line 185 | public class CustomConcurrentHashMap<K,
185           */
186          boolean equal(K key, Object x);
187          /**
188 <         * Returns a hash value such that equal(a, b) implies
188 >         * Returns a hash value such that equal(a, b) implies
189           * hash(a)==hash(b).
190           * @param x an object queried for membership
191           * @return a hash value
# Line 194 | Line 195 | public class CustomConcurrentHashMap<K,
195  
196      // builtin equivalences
197  
198 <    static final class EquivalenceUsingIdentity
198 >    static final class EquivalenceUsingIdentity
199          implements Equivalence<Object>, Serializable {
200          private static final long serialVersionUID = 7259069246764182397L;
201          public final boolean equal(Object a, Object b) { return a == b; }
202          public final int hash(Object a) { return System.identityHashCode(a); }
203      }
204  
205 <    static final class EquivalenceUsingEquals
205 >    static final class EquivalenceUsingEquals
206          implements Equivalence<Object>, Serializable {
207          private static final long serialVersionUID = 7259069247764182397L;
208          public final boolean equal(Object a, Object b) { return a.equals(b); }
# Line 212 | Line 213 | public class CustomConcurrentHashMap<K,
213       * An Equivalence object performing identity-based comparisons
214       * and using {@link System#identityHashCode} for hashing
215       */
216 <    public static final Equivalence<Object> IDENTITY =
216 >    public static final Equivalence<Object> IDENTITY =
217          new EquivalenceUsingIdentity();
218 <    
218 >
219      /**
220       * An Equivalence object performing {@link Object#equals} based comparisons
221       * and using {@link Object#hashCode} hashing
222       */
223 <    public static final Equivalence<Object> EQUALS =
223 >    public static final Equivalence<Object> EQUALS =
224          new EquivalenceUsingEquals();
225  
226      /**
227       * A function computing a mapping from the given key to a value,
228 <     *  or <code>null</code> if there is no mapping.
228 >     * or {@code null} if there is no mapping.
229       */
230 <    public static interface MappingFunction<K, V> {
230 >    public static interface MappingFunction<K,V> {
231          /**
232           * Returns a value for the given key, or null if there is no
233           * mapping. If this function throws an (unchecked) exception,
# Line 236 | Line 237 | public class CustomConcurrentHashMap<K,
237           * simple. The most common usage is to construct a new object
238           * serving as an initial mapped value.
239           *
240 <         * @param key the (nonnull) key
240 >         * @param key the (non-null) key
241           * @return a value, or null if none
242           */
243          V map(K key);
# Line 244 | Line 245 | public class CustomConcurrentHashMap<K,
245  
246      /**
247       * A function computing a new mapping from the given key and its
248 <     * current value to a new value, or <code>null</code> if there is
249 <     * no mapping
248 >     * current value to a new value, or {@code null} if there is
249 >     * no mapping.
250       */
251 <    public static interface RemappingFunction<K, V> {
251 >    public static interface RemappingFunction<K,V> {
252          /**
253           * Returns a new value for the given key and its current, or
254           * null if there is no mapping.
# Line 275 | Line 276 | public class CustomConcurrentHashMap<K,
276       */
277      static interface NodeFactory extends Serializable {
278          /**
279 <         * Creates and returns a Node using the given parameters
279 >         * Creates and returns a Node using the given parameters.
280 >         *
281           * @param locator an opaque immutable locator for this node
282 <         * @parem key the (nonnull) immutable key
283 <         * @parem value the (nonnull) volatile value;
284 <         * @param cchm the table creating this node.
282 >         * @param key the (non-null) immutable key
283 >         * @param value the (non-null) volatile value
284 >         * @param cchm the table creating this node
285           * @param linkage an opaque volatile linkage for maintaining this node
286           */
287 <        Node newNode(int locator, Object key, Object value,
287 >        Node newNode(int locator, Object key, Object value,
288                       CustomConcurrentHashMap cchm, Node linkage);
289      }
290  
# Line 303 | Line 305 | public class CustomConcurrentHashMap<K,
305      static interface Node extends Reclaimable {
306          /**
307           * Returns the key established during the creation of this node.
308 <         * Note: This method is named "get" rether than "getKey"
308 >         * Note: This method is named "get" rather than "getKey"
309           * to simplify usage of Reference keys.
310           * @return the key
311           */
# Line 319 | Line 321 | public class CustomConcurrentHashMap<K,
321           * Returns the value established during the creation of this
322           * node or, if since updated, the value set by the most
323           * recent call to setValue, or throws an exception if
324 <         * value could not be computed
324 >         * value could not be computed.
325           * @return the value
326           * @throws RuntimeException or Error if computeValue failed
327           */
# Line 332 | Line 334 | public class CustomConcurrentHashMap<K,
334          void setValue(Object value);
335  
336          /**
337 <         * Returns the lonkage established during the creation of this
337 >         * Returns the linkage established during the creation of this
338           * node or, if since updated, the linkage set by the most
339           * recent call to setLinkage.
340           * @return the linkage
# Line 343 | Line 345 | public class CustomConcurrentHashMap<K,
345           * Records the linkage to be returned by the next call to getLinkage.
346           * @param linkage the linkage
347           */
348 <        void setLinkage(Node r);
348 >        void setLinkage(Node linkage);
349      }
350  
351      /**
352       * Each Segment holds a count and table corresponding to a segment
353       * of the table. This class contains only those methods for
354       * directly assigning these fields, which must only be called
355 <     * while holding locks
355 >     * while holding locks.
356       */
357      static final class Segment extends ReentrantLock {
358          volatile Node[] table;
359          int count;
360 <        
360 >
361          final void decrementCount() {
362              if (--count == 0)
363                  table = null;
# Line 385 | Line 387 | public class CustomConcurrentHashMap<K,
387          }
388  
389          /**
390 <         * See the similar code in ConcurrentHashMap for explanation
390 >         * See the similar code in ConcurrentHashMap for explanation.
391           */
392          final Node[] resizeTable(CustomConcurrentHashMap cchm) {
393              Node[] oldTable = table;
394              if (oldTable == null)
395 <                return table = (Node[])
394 <                    new Node[cchm.initialSegmentCapacity];
395 >                return table = new Node[cchm.initialSegmentCapacity];
396  
397              int oldCapacity = oldTable.length;
398              if (oldCapacity >= MAX_SEGMENT_CAPACITY)
399                  return oldTable;
400 <            Node[] newTable =
400 <                (Node[])new Node[oldCapacity<<1];
400 >            Node[] newTable = new Node[oldCapacity<<1];
401              int sizeMask = newTable.length - 1;
402              NodeFactory fac = cchm.factory;
403              for (int i = 0; i < oldCapacity ; i++) {
# Line 436 | Line 436 | public class CustomConcurrentHashMap<K,
436                                  (pv = p.getValue()) == null)
437                                  --count;
438                              else
439 <                                newTable[k] =
439 >                                newTable[k] =
440                                      fac.newNode(ph, pk, pv, cchm, newTable[k]);
441                          }
442                      }
# Line 477 | Line 477 | public class CustomConcurrentHashMap<K,
477       * The segments, each of which acts as a hash table
478       */
479      transient volatile Segment[] segments;
480 <    
480 >
481      /**
482       * The factory for this map
483       */
484      final NodeFactory factory;
485 <    
485 >
486      /**
487       * Equivalence object for keys
488       */
489      final Equivalence<? super K> keyEquivalence;
490 <    
490 >
491      /**
492       * Equivalence object for values
493       */
494      final Equivalence<? super V> valueEquivalence;
495 <    
495 >
496      /**
497       * The initial size of Segment tables when they are first constructed
498       */
# Line 515 | Line 515 | public class CustomConcurrentHashMap<K,
515          this.keyEquivalence = keq;
516          this.valueEquivalence = veq;
517          // Reflectively assemble factory name
518 <        String factoryName =
519 <            CustomConcurrentHashMap.class.getName() + "$" +
520 <            ks + "Key" +
518 >        String factoryName =
519 >            CustomConcurrentHashMap.class.getName() + "$" +
520 >            ks + "Key" +
521              vs + "ValueNodeFactory";
522          try {
523              this.factory = (NodeFactory)
# Line 532 | Line 532 | public class CustomConcurrentHashMap<K,
532              int sc = (int)((1L + (4L * es) / 3) >>> SEGMENT_BITS);
533              if (sc < MIN_SEGMENT_CAPACITY)
534                  sc = MIN_SEGMENT_CAPACITY;
535 <            else if (sc > MAX_SEGMENT_CAPACITY)
536 <                sc = MAX_SEGMENT_CAPACITY;
537 <            this.initialSegmentCapacity = sc;
535 >            int capacity = MIN_SEGMENT_CAPACITY; // ensure power of two
536 >            while (capacity < sc)
537 >                capacity <<= 1;
538 >            if (capacity > MAX_SEGMENT_CAPACITY)
539 >                capacity = MAX_SEGMENT_CAPACITY;
540 >            this.initialSegmentCapacity = capacity;
541          }
542 <        this.segments = (Segment[])new Segment[NSEGMENTS];
542 >        this.segments = new Segment[NSEGMENTS];
543      }
544  
545      /**
546 <     * Creates a new CustomConcurrentHashMap with the given parameters
546 >     * Creates a new CustomConcurrentHashMap with the given parameters.
547       * @param keyStrength the strength for keys
548       * @param keyEquivalence the Equivalence to use for keys
549       * @param valueStrength the strength for values
# Line 554 | Line 557 | public class CustomConcurrentHashMap<K,
557                                     Strength valueStrength,
558                                     Equivalence<? super V> valueEquivalence,
559                                     int expectedSize) {
560 <        this(keyStrength.getName(), keyEquivalence,
560 >        this(keyStrength.getName(), keyEquivalence,
561               valueStrength.getName(), valueEquivalence,
562               expectedSize);
563      }
# Line 569 | Line 572 | public class CustomConcurrentHashMap<K,
572  
573      /**
574       * Returns a new map using Integer keys and the given value
575 <     * parameters
575 >     * parameters.
576       * @param valueStrength the strength for values
577       * @param valueEquivalence the Equivalence to use for values
578       * @param expectedSize an estimate of the number of elements
# Line 587 | Line 590 | public class CustomConcurrentHashMap<K,
590      }
591  
592      /**
593 <     * Returns a new map using the given key parameters and Integer values
593 >     * Returns a new map using the given key parameters and Integer values.
594       * @param keyStrength the strength for keys
595       * @param keyEquivalence the Equivalence to use for keys
596       * @param expectedSize an estimate of the number of elements
# Line 600 | Line 603 | public class CustomConcurrentHashMap<K,
603                         Equivalence<? super KeyType> keyEquivalence,
604                         int expectedSize) {
605          return new CustomConcurrentHashMap<KeyType, Integer>
606 <            (keyStrength.getName(), keyEquivalence, INT_STRING, EQUALS,
606 >            (keyStrength.getName(), keyEquivalence, INT_STRING, EQUALS,
607               expectedSize);
608      }
609  
610      /**
611 <     * Returns a new map using Integer keys and values
611 >     * Returns a new map using Integer keys and values.
612       * @param expectedSize an estimate of the number of elements
613       * that will be held in the map. If no estimate is known,
614       * zero is an acceptable value.
# Line 614 | Line 617 | public class CustomConcurrentHashMap<K,
617      public static CustomConcurrentHashMap<Integer, Integer>
618          newIntKeyIntValueMap(int expectedSize) {
619          return new CustomConcurrentHashMap<Integer, Integer>
620 <            (INT_STRING, EQUALS, INT_STRING, EQUALS,
620 >            (INT_STRING, EQUALS, INT_STRING, EQUALS,
621               expectedSize);
622      }
623  
624      /**
625 <     * Returns the segment for traversing table for key with given hash
625 >     * Returns the segment for traversing table for key with given hash.
626       * @param hash the hash code for the key
627       * @return the segment, or null if not yet initialized
628       */
# Line 629 | Line 632 | public class CustomConcurrentHashMap<K,
632  
633      /**
634       * Returns the segment for possibly inserting into the table
635 <     * associated with given hash, constructing it if necesary.
635 >     * associated with given hash, constructing it if necessary.
636       * @param hash the hash code for the key
637       * @return the segment
638       */
# Line 638 | Line 641 | public class CustomConcurrentHashMap<K,
641          int index = (hash >>> SEGMENT_SHIFT) & SEGMENT_MASK;
642          Segment seg = segs[index];
643          if (seg == null) {
644 <            synchronized(segs) {
644 >            synchronized (segs) {
645                  seg = segs[index];
646                  if (seg == null) {
647                      seg = new Segment();
# Line 652 | Line 655 | public class CustomConcurrentHashMap<K,
655      }
656  
657      /**
658 <     * Returns node for key, or null if none
658 >     * Returns node for key, or null if none.
659       */
660      final Node findNode(Object key, int hash, Segment seg) {
661          if (seg != null) {
# Line 662 | Line 665 | public class CustomConcurrentHashMap<K,
665                  while (p != null) {
666                      Object k = p.get();
667                      if (k == key ||
668 <                        (k != null &&
669 <                         p.getLocator() == hash &&
668 >                        (k != null &&
669 >                         p.getLocator() == hash &&
670                           keyEquivalence.equal((K)k, key)))
671                          return p;
672                      p = p.getLinkage();
# Line 674 | Line 677 | public class CustomConcurrentHashMap<K,
677      }
678  
679      /**
680 <     * Returns <tt>true</tt> if this map contains a key equivalent to
680 >     * Returns {@code true} if this map contains a key equivalent to
681       * the given key with respect to this map's key Equivalence.
682       *
683 <     * @param  key   possible key
684 <     * @return <tt>true</tt> if this map contains the specified key
683 >     * @param  key possible key
684 >     * @return {@code true} if this map contains the specified key
685       * @throws NullPointerException if the specified key is null
686       */
687      public boolean containsKey(Object key) {
# Line 693 | Line 696 | public class CustomConcurrentHashMap<K,
696      /**
697       * Returns the value associated with a key equivalent to the given
698       * key with respect to this map's key Equivalence, or {@code null}
699 <     * if no such mapping exists
699 >     * if no such mapping exists.
700       *
701 <     * @param  key   possible key
702 <     * @return the value associated with the kew or <tt>null</tt> if
703 <     * there is no mapping.
701 >     * @param  key possible key
702 >     * @return the value associated with the key, or {@code null} if
703 >     * there is no mapping
704       * @throws NullPointerException if the specified key is null
705       */
706      public V get(Object key) {
# Line 712 | Line 715 | public class CustomConcurrentHashMap<K,
715      }
716  
717      /**
718 <     * Share dimplementation for put, putIfAbsent
718 >     * Shared implementation for put, putIfAbsent
719       */
720      final V doPut(K key, V value, boolean onlyIfNull) {
721          if (key == null || value == null)
# Line 748 | Line 751 | public class CustomConcurrentHashMap<K,
751       *
752       * @param key key with which the specified value is to be associated
753       * @param value value to be associated with the specified key
754 <     * @return the previous value associated with <tt>key</tt>, or
755 <     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
754 >     * @return the previous value associated with {@code key}, or
755 >     *         {@code null} if there was no mapping for {@code key}
756       * @throws NullPointerException if the specified key or value is null
757       */
758      public V put(K key, V value) {
# Line 760 | Line 763 | public class CustomConcurrentHashMap<K,
763       * {@inheritDoc}
764       *
765       * @return the previous value associated with the specified key,
766 <     *         or <tt>null</tt> if there was no mapping for the key
766 >     *         or {@code null} if there was no mapping for the key
767       * @throws NullPointerException if the specified key or value is null
768       */
769      public V putIfAbsent(K key, V value) {
# Line 809 | Line 812 | public class CustomConcurrentHashMap<K,
812       * {@inheritDoc}
813       *
814       * @return the previous value associated with the specified key,
815 <     *         or <tt>null</tt> if there was no mapping for the key
815 >     *         or {@code null} if there was no mapping for the key
816       * @throws NullPointerException if the specified key or value is null
817       */
818      public boolean replace(K key, V oldValue, V newValue) {
# Line 824 | Line 827 | public class CustomConcurrentHashMap<K,
827                  Node r = findNode(key, hash, seg);
828                  if (r != null) {
829                      V v = (V)(r.getValue());
830 <                    if (v == oldValue ||
830 >                    if (v == oldValue ||
831                          (v != null && valueEquivalence.equal(v, oldValue))) {
832                          r.setValue(newValue);
833                          replaced = true;
# Line 841 | Line 844 | public class CustomConcurrentHashMap<K,
844       * Removes the mapping for the specified key.
845       *
846       * @param  key the key to remove
847 <     * @return the previous value associated with <tt>key</tt>, or
848 <     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
847 >     * @return the previous value associated with {@code key}, or
848 >     *         {@code null} if there was no mapping for {@code key}
849       * @throws NullPointerException if the specified key is null
850       */
851      public V remove(Object key) {
# Line 864 | Line 867 | public class CustomConcurrentHashMap<K,
867                          Object k = p.get();
868                          if (k == key ||
869                              (k != null &&
870 <                             p.getLocator() == hash &&
870 >                             p.getLocator() == hash &&
871                               keyEquivalence.equal((K)k, key))) {
872                              oldValue = (V)(p.getValue());
873                              if (pred == null)
874 <                                tab[i] = n;
874 >                                tab[i] = n;
875                              else
876                                  pred.setLinkage(n);
877                              seg.decrementCount();
# Line 911 | Line 914 | public class CustomConcurrentHashMap<K,
914                          Object k = p.get();
915                          if (k == key ||
916                              (k != null &&
917 <                             p.getLocator() == hash &&
917 >                             p.getLocator() == hash &&
918                               keyEquivalence.equal((K)k, key))) {
919                              V v = (V)(p.getValue());
920                              if (v == value ||
921 <                                (v != null &&
921 >                                (v != null &&
922                                   valueEquivalence.equal(v, value))) {
923                                  if (pred == null)
924 <                                    tab[i] = n;
924 >                                    tab[i] = n;
925                                  else
926                                      pred.setLinkage(n);
927                                  seg.decrementCount();
# Line 938 | Line 941 | public class CustomConcurrentHashMap<K,
941      }
942  
943      /**
944 <     * Remove node if its key or value are null
944 >     * Removes node if its key or value are null.
945       */
946      final void removeIfReclaimed(Node r) {
947          int hash = r.getLocator();
# Line 955 | Line 958 | public class CustomConcurrentHashMap<K,
958                      while (p != null) {
959                          Node n = p.getLinkage();
960                          if (p.get() != null && p.getValue() != null) {
961 +                            pred = p;
962 +                            p = n;
963 +                        }
964 +                        else {
965                              if (pred == null)
966 <                                tab[i] = n;
966 >                                tab[i] = n;
967                              else
968                                  pred.setLinkage(n);
969                              seg.decrementCount();
970                              p = n;
971                          }
965                        else {
966                            pred = p;
967                            p = n;
968                        }
972                      }
973                  }
974              } finally {
# Line 975 | Line 978 | public class CustomConcurrentHashMap<K,
978      }
979  
980      /**
981 <     * Returns <tt>true</tt> if this map contains no key-value mappings.
981 >     * Returns {@code true} if this map contains no key-value mappings.
982       *
983 <     * @return <tt>true</tt> if this map contains no key-value mappings
983 >     * @return {@code true} if this map contains no key-value mappings
984       */
985      public final boolean isEmpty() {
986          final Segment[] segs = this.segments;
987          for (int i = 0; i < segs.length; ++i) {
988              Segment seg = segs[i];
989 <            if (seg != null &&
990 <                seg.getTableForTraversal() != null &&
989 >            if (seg != null &&
990 >                seg.getTableForTraversal() != null &&
991                  seg.count != 0)
992                  return false;
993          }
# Line 993 | Line 996 | public class CustomConcurrentHashMap<K,
996  
997      /**
998       * Returns the number of key-value mappings in this map.  If the
999 <     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
1000 <     * <tt>Integer.MAX_VALUE</tt>.
999 >     * map contains more than {@code Integer.MAX_VALUE} elements, returns
1000 >     * {@code Integer.MAX_VALUE}.
1001       *
1002       * @return the number of key-value mappings in this map
1003       */
# Line 1006 | Line 1009 | public class CustomConcurrentHashMap<K,
1009              if (seg != null && seg.getTableForTraversal() != null)
1010                  sum += seg.count;
1011          }
1012 <        return sum >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)sum;
1012 >        return (sum >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) sum;
1013      }
1014  
1015      /**
1016 <     * Returns <tt>true</tt> if this map maps one or more keys to a
1016 >     * Returns {@code true} if this map maps one or more keys to a
1017       * value equivalent to the given value with respect to this map's
1018       * value Equivalence.  Note: This method requires a full internal
1019       * traversal of the hash table, and so is much slower than method
1020 <     * <tt>containsKey</tt>.
1020 >     * {@code containsKey}.
1021       *
1022       * @param value value whose presence in this map is to be tested
1023 <     * @return <tt>true</tt> if this map maps one or more keys to the
1023 >     * @return {@code true} if this map maps one or more keys to the
1024       *         specified value
1025       * @throws NullPointerException if the specified value is null
1026       */
# Line 1030 | Line 1033 | public class CustomConcurrentHashMap<K,
1033              Node[] tab;
1034              if (seg != null && (tab = seg.getTableForTraversal()) != null) {
1035                  for (int j = 0; j < tab.length; ++j) {
1036 <                    for (Node p = tab[j];
1037 <                         p != null;
1036 >                    for (Node p = tab[j];
1037 >                         p != null;
1038                           p = p.getLinkage()) {
1039                          V v = (V)(p.getValue());
1040                          if (v == value ||
# Line 1065 | Line 1068 | public class CustomConcurrentHashMap<K,
1068      /**
1069       * If the specified key is not already associated with a value,
1070       * computes its value using the given mappingFunction, and if
1071 <     * nonnull, enters it into the map.  This is equivalent to
1071 >     * non-null, enters it into the map.  This is equivalent to
1072       *
1073       * <pre>
1074       *   if (map.containsKey(key))
# Line 1078 | Line 1081 | public class CustomConcurrentHashMap<K,
1081       * </pre>
1082       *
1083       * except that the action is performed atomically.  Some
1084 <     * attemmpted operations on this map by other threads may be
1084 >     * attempted operations on this map by other threads may be
1085       * blocked while computation is in progress. Because this function
1086       * is invoked within atomicity control, the computation should be
1087       * short and simple. The most common usage is to construct a new
# Line 1086 | Line 1089 | public class CustomConcurrentHashMap<K,
1089       *
1090       * @param key key with which the specified value is to be associated
1091       * @param mappingFunction the function to compute a value
1092 <     * @return the current (existing or computed) value associated with
1093 <     *         the specified key, or <tt>null</tt> if the computation
1094 <     *         returned <tt>null</tt>.
1095 <     * @throws NullPointerException if the specified key or mappingFunction
1096 <     *         is null,
1092 >     * @return the current (existing or computed) value associated with
1093 >     *         the specified key, or {@code null} if the computation
1094 >     *         returned {@code null}
1095 >     * @throws NullPointerException if the specified key or mappingFunction
1096 >     *         is null
1097       * @throws RuntimeException or Error if the mappingFunction does so,
1098 <     *         in which case the mapping is left unestablished.
1098 >     *         in which case the mapping is left unestablished
1099       */
1100      public V computeIfAbsent(K key, MappingFunction<? super K, ? extends V> mappingFunction) {
1101          if (key == null || mappingFunction == null)
# Line 1111 | Line 1114 | public class CustomConcurrentHashMap<K,
1114                      // Map is OK if function throws exception
1115                      v = mappingFunction.map(key);
1116                      if (v != null) {
1117 <                        if (r != null)
1117 >                        if (r != null)
1118                              r.setValue(v);
1119                          else {
1120                              Node[] tab = seg.getTableForAdd(this);
# Line 1144 | Line 1147 | public class CustomConcurrentHashMap<K,
1147       *   else
1148       *     return remove(key);
1149       * </pre>
1150 <     *
1151 <     * except that the action is performed atomically. Some attemmpted
1150 >     *
1151 >     * except that the action is performed atomically. Some attempted
1152       * operations on this map by other threads may be blocked while
1153       * computation is in progress.
1154       *
# Line 1154 | Line 1157 | public class CustomConcurrentHashMap<K,
1157       * <pre>
1158       * map.compute(word, new RemappingFunction&lt;String,Integer&gt;() {
1159       *   public Integer remap(String k, Integer v) {
1160 <     *     return v == null? 1 : v + 1;
1160 >     *     return (v == null) ? 1 : v + 1;
1161       *   }});
1162       * </pre>
1163       *
1164       * @param key key with which the specified value is to be associated
1165       * @param remappingFunction the function to compute a value
1166       * @return the updated value or
1167 <     *         <tt>null</tt> if the computation returned <tt>null</tt>
1168 <     * @throws NullPointerException if the specified key or remappingFunction
1169 <     *         is null,
1167 >     *         {@code null} if the computation returned {@code null}
1168 >     * @throws NullPointerException if the specified key or remappingFunction
1169 >     *         is null
1170       * @throws RuntimeException or Error if the remappingFunction does so,
1171       *         in which case the mapping is left in its previous state
1172       */
# Line 1183 | Line 1186 | public class CustomConcurrentHashMap<K,
1186                  K k = (K)(p.get());
1187                  if (k == key ||
1188                      (k != null &&
1189 <                     p.getLocator() == hash &&
1189 >                     p.getLocator() == hash &&
1190                       keyEquivalence.equal(k, key))) {
1191                      value = (V)(p.getValue());
1192                      break;
# Line 1193 | Line 1196 | public class CustomConcurrentHashMap<K,
1196              }
1197              value = remappingFunction.remap(key, value);
1198              if (p != null) {
1199 <                if (value != null)
1199 >                if (value != null)
1200                      p.setValue(value);
1201                  else {
1202                      Node n = p.getLinkage();
1203                      if (pred == null)
1204 <                        tab[i] = n;
1204 >                        tab[i] = n;
1205                      else
1206                          pred.setLinkage(n);
1207                      seg.decrementCount();
1208                  }
1209              }
1210              else if (value != null) {
1211 <                Node r =
1211 >                Node r =
1212                      factory.newNode(hash, key, value, this, tab[i]);
1213                  // Fences.preStoreFence(r);
1214                  // tab[i] = r;
# Line 1254 | Line 1257 | public class CustomConcurrentHashMap<K,
1257                  else if (nextSegmentIndex >= 0) {
1258                      Segment seg = segments[nextSegmentIndex--];
1259                      Node[] t;
1260 <                    if (seg != null &&
1260 >                    if (seg != null &&
1261                          (t = seg.getTableForTraversal()) != null) {
1262                          currentTable = t;
1263                          nextTableIndex = t.length - 1;
# Line 1287 | Line 1290 | public class CustomConcurrentHashMap<K,
1290          final Map.Entry<K,V> nextEntry() {
1291              if (nextNode == null)
1292                  throw new NoSuchElementException();
1293 <            WriteThroughEntry e = new WriteThroughEntry((K)nextKey,
1293 >            WriteThroughEntry e = new WriteThroughEntry((K)nextKey,
1294                                                          (V)nextValue);
1295              advance();
1296              return e;
# Line 1330 | Line 1333 | public class CustomConcurrentHashMap<K,
1333          }
1334      }
1335  
1336 <    final class KeyIterator extends HashIterator
1336 >    final class KeyIterator extends HashIterator
1337          implements Iterator<K> {
1338 <        public K next() {
1339 <            return super.nextKey();
1338 >        public K next() {
1339 >            return super.nextKey();
1340          }
1341      }
1342  
# Line 1341 | Line 1344 | public class CustomConcurrentHashMap<K,
1344          return new KeyIterator();
1345      }
1346  
1347 <    final class ValueIterator extends HashIterator
1347 >    final class ValueIterator extends HashIterator
1348          implements Iterator<V> {
1349 <        public V next() {
1350 <            return super.nextValue();
1349 >        public V next() {
1350 >            return super.nextValue();
1351          }
1352      }
1353  
1354 <    final class EntryIterator extends HashIterator
1354 >    final class EntryIterator extends HashIterator
1355          implements Iterator<Map.Entry<K,V>> {
1356          public Map.Entry<K,V> next() {
1357              return super.nextEntry();
# Line 1403 | Line 1406 | public class CustomConcurrentHashMap<K,
1406                  return false;
1407              Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1408              V v = CustomConcurrentHashMap.this.get(e.getKey());
1409 <            return v != null &&
1409 >            return v != null &&
1410                  valueEquivalence.equal(v, e.getValue());
1411          }
1412          public boolean remove(Object o) {
1413              if (!(o instanceof Map.Entry))
1414                  return false;
1415              Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1416 <            return CustomConcurrentHashMap.this.remove(e.getKey(), e.getValue());
1416 >            return CustomConcurrentHashMap.this.remove(e.getKey(),
1417 >                                                       e.getValue());
1418          }
1419          public int size() {
1420              return CustomConcurrentHashMap.this.size();
# Line 1428 | Line 1432 | public class CustomConcurrentHashMap<K,
1432       * The set is backed by the map, so changes to the map are
1433       * reflected in the set, and vice-versa.  The set supports element
1434       * removal, which removes the corresponding mapping from this map,
1435 <     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1436 <     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
1437 <     * operations.  It does not support the <tt>add</tt> or
1438 <     * <tt>addAll</tt> operations.
1435 >     * via the {@code Iterator.remove}, {@code Set.remove},
1436 >     * {@code removeAll}, {@code retainAll}, and {@code clear}
1437 >     * operations.  It does not support the {@code add} or
1438 >     * {@code addAll} operations.
1439       *
1440 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1440 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1441       * that will never throw {@link ConcurrentModificationException},
1442       * and guarantees to traverse elements as they existed upon
1443       * construction of the iterator, and may (but is not guaranteed to)
# Line 1449 | Line 1453 | public class CustomConcurrentHashMap<K,
1453       * The collection is backed by the map, so changes to the map are
1454       * reflected in the collection, and vice-versa.  The collection
1455       * supports element removal, which removes the corresponding
1456 <     * mapping from this map, via the <tt>Iterator.remove</tt>,
1457 <     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1458 <     * <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not
1459 <     * support the <tt>add</tt> or <tt>addAll</tt> operations.
1456 >     * mapping from this map, via the {@code Iterator.remove},
1457 >     * {@code Collection.remove}, {@code removeAll},
1458 >     * {@code retainAll}, and {@code clear} operations.  It does not
1459 >     * support the {@code add} or {@code addAll} operations.
1460       *
1461 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1461 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1462       * that will never throw {@link ConcurrentModificationException},
1463       * and guarantees to traverse elements as they existed upon
1464       * construction of the iterator, and may (but is not guaranteed to)
# Line 1470 | Line 1474 | public class CustomConcurrentHashMap<K,
1474       * The set is backed by the map, so changes to the map are
1475       * reflected in the set, and vice-versa.  The set supports element
1476       * removal, which removes the corresponding mapping from the map,
1477 <     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1478 <     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
1479 <     * operations.  It does not support the <tt>add</tt> or
1480 <     * <tt>addAll</tt> operations.
1477 >     * via the {@code Iterator.remove}, {@code Set.remove},
1478 >     * {@code removeAll}, {@code retainAll}, and {@code clear}
1479 >     * operations.  It does not support the {@code add} or
1480 >     * {@code addAll} operations.
1481       *
1482 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1482 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1483       * that will never throw {@link ConcurrentModificationException},
1484       * and guarantees to traverse elements as they existed upon
1485       * construction of the iterator, and may (but is not guaranteed to)
# Line 1490 | Line 1494 | public class CustomConcurrentHashMap<K,
1494  
1495      /**
1496       * Compares the specified object with this map for equality.
1497 <     * Returns <tt>true</tt> if the given object is also a map of the
1497 >     * Returns {@code true} if the given object is also a map of the
1498       * same size, holding keys that are equal using this Map's key
1499       * Equivalence, and which map to values that are equal according
1500       * to this Map's value equivalence.
1501       *
1502       * @param o object to be compared for equality with this map
1503 <     * @return <tt>true</tt> if the specified object is equal to this map
1503 >     * @return {@code true} if the specified object is equal to this map
1504       */
1505      public boolean equals(Object o) {
1506          if (o == this)
1507              return true;
1508 <            
1508 >
1509          if (!(o instanceof Map))
1510              return false;
1511          Map<K,V> m = (Map<K,V>) o;
# Line 1533 | Line 1537 | public class CustomConcurrentHashMap<K,
1537  
1538      /**
1539       * Returns the sum of the hash codes of each entry in this map's
1540 <     * <tt>entrySet()</tt> view, which in turn are the hash codes
1540 >     * {@code entrySet()} view, which in turn are the hash codes
1541       * computed using key and value Equivalences for this Map.
1542       * @return the hash code
1543       */
# Line 1546 | Line 1550 | public class CustomConcurrentHashMap<K,
1550      }
1551  
1552      /**
1553 <     * Save the state of the instance to a stream (i.e., serialize
1554 <     * it).
1553 >     * Saves the state of the instance to a stream (i.e., serializes it).
1554 >     *
1555       * @param s the stream
1556       * @serialData
1557       * the key (Object) and value (Object)
1558       * for each key-value mapping, followed by a null pair.
1559       * The key-value mappings are emitted in no particular order.
1560       */
1561 <    private void writeObject(java.io.ObjectOutputStream s) throws IOException  {
1561 >    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1562          s.defaultWriteObject();
1563          for (Map.Entry<K,V> e : entrySet()) {
1564              s.writeObject(e.getKey());
# Line 1565 | Line 1569 | public class CustomConcurrentHashMap<K,
1569      }
1570  
1571      /**
1572 <     * Reconstitute the instance from a stream (i.e., deserialize it).
1572 >     * Reconstitutes the instance from a stream (that is, deserializes it).
1573       * @param s the stream
1574       */
1575      private void readObject(java.io.ObjectInputStream s)
1576 <        throws IOException, ClassNotFoundException  {
1576 >        throws IOException, ClassNotFoundException {
1577          s.defaultReadObject();
1578 <        this.segments = (Segment[])(new Segment[NSEGMENTS]);
1578 >        this.segments = new Segment[NSEGMENTS];
1579          for (;;) {
1580              K key = (K) s.readObject();
1581              V value = (V) s.readObject();
# Line 1583 | Line 1587 | public class CustomConcurrentHashMap<K,
1587  
1588      /**
1589       * A hash-based set with properties identical to those of
1590 <     * <code>Collections.newSetFromMap</code> applied to a
1591 <     * <code>CustomConcurrentHashMap</code>, but possibly more
1590 >     * {@code Collections.newSetFromMap} applied to a
1591 >     * {@code CustomConcurrentHashMap}, but possibly more
1592       * space-efficient.  The set does not permit null elements. The
1593       * set is serializable; however, serializing a set that uses soft
1594       * or weak references can give unpredictable results.
# Line 1595 | Line 1599 | public class CustomConcurrentHashMap<K,
1599          final CustomConcurrentHashMap<K,K> cchm;
1600  
1601          /**
1602 <         * Creates a set with the given parameters
1602 >         * Creates a set with the given parameters.
1603           * @param strength the strength of elements
1604           * @param equivalence the Equivalence to use
1605           * @param expectedSize an estimate of the number of elements
1606           * that will be held in the set. If no estimate is known, zero
1607           * is an acceptable value.
1608           */
1609 <        public KeySet(Strength strength,
1609 >        public KeySet(Strength strength,
1610                        Equivalence<? super K> equivalence,
1611                        int expectedSize) {
1612              this.cchm = new CustomConcurrentHashMap<K,K>
1613 <                (strength.getName(), equivalence,
1613 >                (strength.getName(), equivalence,
1614                   SELF_STRING, equivalence, expectedSize);
1615          }
1616  
# Line 1614 | Line 1618 | public class CustomConcurrentHashMap<K,
1618           * Returns an element equivalent to the given element with
1619           * respect to this set's Equivalence, if such an element
1620           * exists, else adds and returns the given element.
1621 <         *
1621 >         *
1622           * @param e the element
1623 <         * @return e, or an element equivalent to e.
1623 >         * @return e, or an element equivalent to e
1624           */
1625          public K intern(K e) {
1626              K oldElement = cchm.doPut(e, e, true);
1627 <            return (oldElement != null) ? oldElement : e;
1627 >            return (oldElement != null) ? oldElement : e;
1628          }
1629 <        
1629 >
1630          /**
1631 <         * Returns <tt>true</tt> if this set contains an
1631 >         * Returns {@code true} if this set contains an
1632           * element equivalent to the given element with respect
1633           * to this set's Equivalence.
1634           * @param o element whose presence in this set is to be tested
1635 <         * @return <tt>true</tt> if this set contains the specified element
1635 >         * @return {@code true} if this set contains the specified element
1636           */
1637          public boolean contains(Object o) {
1638              return cchm.containsKey(o);
1639          }
1640 <        
1640 >
1641          /**
1642           * Returns a <i>weakly consistent iterator</i> over the
1643           * elements in this set, that may reflect some, all or none of
# Line 1644 | Line 1648 | public class CustomConcurrentHashMap<K,
1648          public Iterator<K> iterator() {
1649              return cchm.keyIterator();
1650          }
1651 <        
1651 >
1652          /**
1653           * Adds the specified element to this set if there is not
1654           * already an element equivalent to the given element with
1655           * respect to this set's Equivalence.
1656           *
1657           * @param e element to be added to this set
1658 <         * @return <tt>true</tt> if this set did not already contain
1658 >         * @return {@code true} if this set did not already contain
1659           * the specified element
1660           */
1661          public boolean add(K e) {
# Line 1663 | Line 1667 | public class CustomConcurrentHashMap<K,
1667           * respect to this set's Equivalence, if one is present.
1668           *
1669           * @param o object to be removed from this set, if present
1670 <         * @return <tt>true</tt> if the set contained the specified element
1670 >         * @return {@code true} if the set contained the specified element
1671           */
1672          public boolean remove(Object o) {
1673              return cchm.remove(o) != null;
1674          }
1675  
1676          /**
1677 <         * Returns <tt>true</tt> if this set contains no elements.
1677 >         * Returns {@code true} if this set contains no elements.
1678           *
1679 <         * @return <tt>true</tt> if this set contains no elements
1679 >         * @return {@code true} if this set contains no elements
1680           */
1681          public boolean isEmpty() {
1682              return cchm.isEmpty();
# Line 1686 | Line 1690 | public class CustomConcurrentHashMap<K,
1690          public int size() {
1691              return cchm.size();
1692          }
1693 <        
1693 >
1694          /**
1695           * Removes all of the elements from this set.
1696           */
# Line 1717 | Line 1721 | public class CustomConcurrentHashMap<K,
1721       * to {@link java.lang.ref.Reference} constructors to arrange
1722       * removal of reclaimed nodes from maps via a background thread.
1723       * @return the reference queue associated with the background
1724 <     * cleanup thread.
1724 >     * cleanup thread
1725       */
1726      static ReferenceQueue<Object> getReclamationQueue() {
1727          ReferenceQueue<Object> q = refQueue;
# Line 1749 | Line 1753 | public class CustomConcurrentHashMap<K,
1753                      Reference<?> r = q.remove();
1754                      if (r instanceof Reclaimable)
1755                          ((Reclaimable)r).onReclamation();
1756 <                } catch (InterruptedException e) {
1757 <                    /* ignore */
1756 >                } catch (InterruptedException e) {
1757 >                    /* ignore */
1758                  }
1759              }
1760          }
# Line 1758 | Line 1762 | public class CustomConcurrentHashMap<K,
1762  
1763      // classes extending Weak/soft refs embedded in reclaimable nodes
1764  
1765 <    static class EmbeddedWeakReference extends WeakReference
1765 >    static class EmbeddedWeakReference extends WeakReference
1766          implements Reclaimable {
1767          final Reclaimable outer;
1768          EmbeddedWeakReference(Object x, Reclaimable outer) {
1769              super(x, getReclamationQueue());
1770              this.outer = outer;
1771          }
1772 <        public final void onReclamation() {
1772 >        public final void onReclamation() {
1773              clear();
1774 <            outer.onReclamation();
1774 >            outer.onReclamation();
1775          }
1776      }
1777  
1778 <    static class EmbeddedSoftReference extends SoftReference
1778 >    static class EmbeddedSoftReference extends SoftReference
1779          implements Reclaimable {
1780          final Reclaimable outer;
1781          EmbeddedSoftReference(Object x, Reclaimable outer) {
1782              super(x, getReclamationQueue());
1783              this.outer = outer;
1784          }
1785 <        public final void onReclamation() {
1785 >        public final void onReclamation() {
1786              clear();
1787 <            outer.onReclamation();
1787 >            outer.onReclamation();
1788          }
1789      }
1790  
# Line 1788 | Line 1792 | public class CustomConcurrentHashMap<K,
1792  
1793      // Strong Keys
1794  
1795 <    static abstract class StrongKeyNode implements Node {
1795 >    abstract static class StrongKeyNode implements Node {
1796          final Object key;
1797          final int locator;
1798          StrongKeyNode(int locator, Object key) {
# Line 1800 | Line 1804 | public class CustomConcurrentHashMap<K,
1804      }
1805  
1806  
1807 <    static abstract class StrongKeySelfValueNode
1807 >    abstract static class StrongKeySelfValueNode
1808          extends StrongKeyNode {
1809          StrongKeySelfValueNode(int locator, Object key) {
1810              super(locator, key);
# Line 1810 | Line 1814 | public class CustomConcurrentHashMap<K,
1814          public final void onReclamation() { }
1815      }
1816  
1817 <    static final class TerminalStrongKeySelfValueNode
1817 >    static final class TerminalStrongKeySelfValueNode
1818          extends StrongKeySelfValueNode {
1819          TerminalStrongKeySelfValueNode(int locator, Object key) {
1820              super(locator, key);
1821          }
1822          public final Node getLinkage() { return null; }
1823 <        public final void setLinkage(Node r) { }
1823 >        public final void setLinkage(Node linkage) { }
1824      }
1825  
1826 <    static final class LinkedStrongKeySelfValueNode
1826 >    static final class LinkedStrongKeySelfValueNode
1827          extends StrongKeySelfValueNode {
1828          volatile Node linkage;
1829 <        LinkedStrongKeySelfValueNode(int locator, Object key,
1829 >        LinkedStrongKeySelfValueNode(int locator, Object key,
1830                                       Node linkage) {
1831              super(locator, key);
1832              this.linkage = linkage;
1833          }
1834          public final Node getLinkage() { return linkage; }
1835 <        public final void setLinkage(Node r) { linkage = r; }
1835 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
1836      }
1837  
1838      static final class StrongKeySelfValueNodeFactory
1839          implements NodeFactory, Serializable {
1840          private static final long serialVersionUID = 7249069346764182397L;
1841          public final Node newNode(int locator,
1842 <                                  Object key, Object value,
1842 >                                  Object key, Object value,
1843                                    CustomConcurrentHashMap cchm,
1844                                    Node linkage) {
1845              if (linkage == null)
# Line 1845 | Line 1849 | public class CustomConcurrentHashMap<K,
1849                  return new LinkedStrongKeySelfValueNode
1850                      (locator, key, linkage);
1851          }
1852 <    }        
1852 >    }
1853  
1854 <    static abstract class StrongKeyStrongValueNode
1854 >    abstract static class StrongKeyStrongValueNode
1855          extends StrongKeyNode {
1856          volatile Object value;
1857          StrongKeyStrongValueNode(int locator, Object key, Object value) {
# Line 1859 | Line 1863 | public class CustomConcurrentHashMap<K,
1863          public final void onReclamation() { }
1864      }
1865  
1866 <    static final class TerminalStrongKeyStrongValueNode
1866 >    static final class TerminalStrongKeyStrongValueNode
1867          extends StrongKeyStrongValueNode {
1868          TerminalStrongKeyStrongValueNode(int locator,
1869                                           Object key, Object value) {
1870              super(locator, key, value);
1871          }
1872          public final Node getLinkage() { return null; }
1873 <        public final void setLinkage(Node r) { }
1873 >        public final void setLinkage(Node linkage) { }
1874      }
1875  
1876 <    static final class LinkedStrongKeyStrongValueNode
1876 >    static final class LinkedStrongKeyStrongValueNode
1877          extends StrongKeyStrongValueNode {
1878          volatile Node linkage;
1879          LinkedStrongKeyStrongValueNode(int locator,
1880 <                                       Object key, Object value,
1880 >                                       Object key, Object value,
1881                                         Node linkage) {
1882              super(locator, key, value);
1883              this.linkage = linkage;
1884          }
1885          public final Node getLinkage() { return linkage; }
1886 <        public final void setLinkage(Node r) { linkage = r; }
1886 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
1887      }
1888  
1889 <    static final class StrongKeyStrongValueNodeFactory
1889 >    static final class StrongKeyStrongValueNodeFactory
1890          implements NodeFactory, Serializable {
1891          private static final long serialVersionUID = 7249069346764182397L;
1892          public final Node newNode(int locator,
1893 <                                  Object key, Object value,
1893 >                                  Object key, Object value,
1894                                    CustomConcurrentHashMap cchm,
1895                                    Node linkage) {
1896              if (linkage == null)
# Line 1896 | Line 1900 | public class CustomConcurrentHashMap<K,
1900                  return new LinkedStrongKeyStrongValueNode
1901                      (locator, key, value, linkage);
1902          }
1903 <    }        
1903 >    }
1904  
1905      // ...
1906  
1907 <    static abstract class StrongKeyIntValueNode
1907 >    abstract static class StrongKeyIntValueNode
1908          extends StrongKeyNode {
1909          volatile int value;
1910          StrongKeyIntValueNode(int locator, Object key, Object value) {
# Line 1908 | Line 1912 | public class CustomConcurrentHashMap<K,
1912              this.value = ((Integer)value).intValue();
1913          }
1914          public final Object getValue() { return Integer.valueOf(value); }
1915 <        public final void setValue(Object value) {
1915 >        public final void setValue(Object value) {
1916              this.value = ((Integer)value).intValue();
1917          }
1918          public final void onReclamation() { }
1919      }
1920  
1921 <    static final class TerminalStrongKeyIntValueNode
1921 >    static final class TerminalStrongKeyIntValueNode
1922          extends StrongKeyIntValueNode {
1923          TerminalStrongKeyIntValueNode(int locator,
1924                                           Object key, Object value) {
1925              super(locator, key, value);
1926          }
1927          public final Node getLinkage() { return null; }
1928 <        public final void setLinkage(Node r) { }
1928 >        public final void setLinkage(Node linkage) { }
1929      }
1930  
1931 <    static final class LinkedStrongKeyIntValueNode
1931 >    static final class LinkedStrongKeyIntValueNode
1932          extends StrongKeyIntValueNode {
1933          volatile Node linkage;
1934          LinkedStrongKeyIntValueNode(int locator,
1935 <                                       Object key, Object value,
1935 >                                       Object key, Object value,
1936                                         Node linkage) {
1937              super(locator, key, value);
1938              this.linkage = linkage;
1939          }
1940          public final Node getLinkage() { return linkage; }
1941 <        public final void setLinkage(Node r) { linkage = r; }
1941 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
1942      }
1943  
1944 <    static final class StrongKeyIntValueNodeFactory
1944 >    static final class StrongKeyIntValueNodeFactory
1945          implements NodeFactory, Serializable {
1946          private static final long serialVersionUID = 7249069346764182397L;
1947          public final Node newNode(int locator,
1948 <                                  Object key, Object value,
1948 >                                  Object key, Object value,
1949                                    CustomConcurrentHashMap cchm,
1950                                    Node linkage) {
1951              if (linkage == null)
# Line 1951 | Line 1955 | public class CustomConcurrentHashMap<K,
1955                  return new LinkedStrongKeyIntValueNode
1956                      (locator, key, value, linkage);
1957          }
1958 <    }        
1958 >    }
1959  
1960      // ...
1961  
1962 <    static abstract class StrongKeyWeakValueNode
1962 >    abstract static class StrongKeyWeakValueNode
1963          extends StrongKeyNode {
1964          volatile EmbeddedWeakReference valueRef;
1965          final CustomConcurrentHashMap cchm;
1966 <        StrongKeyWeakValueNode(int locator, Object key, Object value,
1966 >        StrongKeyWeakValueNode(int locator, Object key, Object value,
1967                                 CustomConcurrentHashMap cchm) {
1968              super(locator, key);
1969              this.cchm = cchm;
# Line 1971 | Line 1975 | public class CustomConcurrentHashMap<K,
1975          }
1976          public final Object getValue() {
1977              EmbeddedWeakReference vr = valueRef;
1978 <            return vr == null? null : vr.get();
1978 >            return (vr == null) ? null : vr.get();
1979          }
1980          public final void setValue(Object value) {
1981              if (value == null)
# Line 1981 | Line 1985 | public class CustomConcurrentHashMap<K,
1985          }
1986      }
1987  
1988 <    static final class TerminalStrongKeyWeakValueNode
1988 >    static final class TerminalStrongKeyWeakValueNode
1989          extends StrongKeyWeakValueNode {
1990          TerminalStrongKeyWeakValueNode(int locator,
1991 <                                       Object key, Object value,
1991 >                                       Object key, Object value,
1992                                         CustomConcurrentHashMap cchm) {
1993              super(locator, key, value, cchm);
1994          }
1995          public final Node getLinkage() { return null; }
1996 <        public final void setLinkage(Node r) { }
1996 >        public final void setLinkage(Node linkage) { }
1997      }
1998  
1999 <    static final class LinkedStrongKeyWeakValueNode
1999 >    static final class LinkedStrongKeyWeakValueNode
2000          extends StrongKeyWeakValueNode {
2001          volatile Node linkage;
2002          LinkedStrongKeyWeakValueNode(int locator,
2003 <                                     Object key, Object value,
2003 >                                     Object key, Object value,
2004                                       CustomConcurrentHashMap cchm,
2005                                       Node linkage) {
2006              super(locator, key, value, cchm);
2007              this.linkage = linkage;
2008          }
2009          public final Node getLinkage() { return linkage; }
2010 <        public final void setLinkage(Node r) { linkage = r; }
2010 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2011      }
2012  
2013 <    static final class StrongKeyWeakValueNodeFactory
2013 >    static final class StrongKeyWeakValueNodeFactory
2014          implements NodeFactory, Serializable {
2015          private static final long serialVersionUID = 7249069346764182397L;
2016 <        public final Node newNode(int locator,
2017 <                                  Object key, Object value,
2016 >        public final Node newNode(int locator,
2017 >                                  Object key, Object value,
2018                                    CustomConcurrentHashMap cchm,
2019                                    Node linkage) {
2020              if (linkage == null)
# Line 2020 | Line 2024 | public class CustomConcurrentHashMap<K,
2024                  return new LinkedStrongKeyWeakValueNode
2025                      (locator, key, value, cchm, linkage);
2026          }
2027 <    }        
2027 >    }
2028  
2029  
2030 <    static abstract class StrongKeySoftValueNode
2030 >    abstract static class StrongKeySoftValueNode
2031          extends StrongKeyNode {
2032          volatile EmbeddedSoftReference valueRef;
2033          final CustomConcurrentHashMap cchm;
2034 <        StrongKeySoftValueNode(int locator, Object key, Object value,
2034 >        StrongKeySoftValueNode(int locator, Object key, Object value,
2035                                 CustomConcurrentHashMap cchm) {
2036              super(locator, key);
2037              this.cchm = cchm;
# Line 2039 | Line 2043 | public class CustomConcurrentHashMap<K,
2043          }
2044          public final Object getValue() {
2045              EmbeddedSoftReference vr = valueRef;
2046 <            return vr == null? null : vr.get();
2046 >            return (vr == null) ? null : vr.get();
2047          }
2048          public final void setValue(Object value) {
2049              if (value == null)
# Line 2049 | Line 2053 | public class CustomConcurrentHashMap<K,
2053          }
2054      }
2055  
2056 <    static final class TerminalStrongKeySoftValueNode
2056 >    static final class TerminalStrongKeySoftValueNode
2057          extends StrongKeySoftValueNode {
2058          TerminalStrongKeySoftValueNode(int locator,
2059 <                                       Object key, Object value,
2059 >                                       Object key, Object value,
2060                                         CustomConcurrentHashMap cchm) {
2061              super(locator, key, value, cchm);
2062          }
2063          public final Node getLinkage() { return null; }
2064 <        public final void setLinkage(Node r) { }
2064 >        public final void setLinkage(Node linkage) { }
2065      }
2066  
2067 <    static final class LinkedStrongKeySoftValueNode
2067 >    static final class LinkedStrongKeySoftValueNode
2068          extends StrongKeySoftValueNode {
2069          volatile Node linkage;
2070          LinkedStrongKeySoftValueNode(int locator,
2071 <                                     Object key, Object value,
2071 >                                     Object key, Object value,
2072                                       CustomConcurrentHashMap cchm,
2073                                       Node linkage) {
2074              super(locator, key, value, cchm);
2075              this.linkage = linkage;
2076          }
2077          public final Node getLinkage() { return linkage; }
2078 <        public final void setLinkage(Node r) { linkage = r; }
2078 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2079      }
2080  
2081 <    static final class StrongKeySoftValueNodeFactory
2081 >    static final class StrongKeySoftValueNodeFactory
2082          implements NodeFactory, Serializable {
2083          private static final long serialVersionUID = 7249069346764182397L;
2084 <        public final Node newNode(int locator,
2085 <                                  Object key, Object value,
2084 >        public final Node newNode(int locator,
2085 >                                  Object key, Object value,
2086                                    CustomConcurrentHashMap cchm,
2087                                    Node linkage) {
2088              if (linkage == null)
# Line 2088 | Line 2092 | public class CustomConcurrentHashMap<K,
2092                  return new LinkedStrongKeySoftValueNode
2093                      (locator, key, value, cchm, linkage);
2094          }
2095 <    }        
2095 >    }
2096  
2097      // Weak keys
2098  
2099 <    static abstract class WeakKeyNode extends WeakReference
2099 >    abstract static class WeakKeyNode extends WeakReference
2100          implements Node {
2101          final int locator;
2102          final CustomConcurrentHashMap cchm;
2103          WeakKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2104 <            super(key);
2104 >            super(key, getReclamationQueue());
2105              this.locator = locator;
2106              this.cchm = cchm;
2107          }
2108          public final int getLocator() { return locator; }
2109 <        public final void onReclamation() {
2109 >        public final void onReclamation() {
2110              clear();
2111              cchm.removeIfReclaimed(this);
2112          }
2113      }
2114  
2115 <    static abstract class WeakKeySelfValueNode
2115 >    abstract static class WeakKeySelfValueNode
2116          extends WeakKeyNode {
2117 <        WeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2117 >        WeakKeySelfValueNode(int locator, Object key,
2118 >                             CustomConcurrentHashMap cchm) {
2119              super(locator, key, cchm);
2120          }
2121          public final Object getValue() { return get(); }
2122          public final void setValue(Object value) { }
2123      }
2124  
2125 <    static final class TerminalWeakKeySelfValueNode
2125 >    static final class TerminalWeakKeySelfValueNode
2126          extends WeakKeySelfValueNode {
2127 <        TerminalWeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2127 >        TerminalWeakKeySelfValueNode(int locator, Object key,
2128 >                                     CustomConcurrentHashMap cchm) {
2129              super(locator, key, cchm);
2130          }
2131          public final Node getLinkage() { return null; }
2132 <        public final void setLinkage(Node r) { }
2132 >        public final void setLinkage(Node linkage) { }
2133      }
2134  
2135 <    static final class LinkedWeakKeySelfValueNode
2135 >    static final class LinkedWeakKeySelfValueNode
2136          extends WeakKeySelfValueNode {
2137          volatile Node linkage;
2138 <        LinkedWeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm,
2138 >        LinkedWeakKeySelfValueNode(int locator, Object key,
2139 >                                   CustomConcurrentHashMap cchm,
2140                                     Node linkage) {
2141              super(locator, key, cchm);
2142              this.linkage = linkage;
2143          }
2144          public final Node getLinkage() { return linkage; }
2145 <        public final void setLinkage(Node r) { linkage = r; }
2145 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2146      }
2147  
2148      static final class WeakKeySelfValueNodeFactory
2149          implements NodeFactory, Serializable {
2150          private static final long serialVersionUID = 7249069346764182397L;
2151          public final Node newNode(int locator,
2152 <                                  Object key, Object value,
2152 >                                  Object key, Object value,
2153                                    CustomConcurrentHashMap cchm,
2154                                    Node linkage) {
2155              if (linkage == null)
# Line 2152 | Line 2159 | public class CustomConcurrentHashMap<K,
2159                  return new LinkedWeakKeySelfValueNode
2160                      (locator, key, cchm, linkage);
2161          }
2162 <    }        
2162 >    }
2163  
2164  
2165 <    static abstract class WeakKeyStrongValueNode
2165 >    abstract static class WeakKeyStrongValueNode
2166          extends WeakKeyNode {
2167          volatile Object value;
2168 <        WeakKeyStrongValueNode(int locator, Object key, Object value, CustomConcurrentHashMap cchm) {
2168 >        WeakKeyStrongValueNode(int locator, Object key, Object value,
2169 >                               CustomConcurrentHashMap cchm) {
2170              super(locator, key, cchm);
2171              this.value = value;
2172          }
# Line 2166 | Line 2174 | public class CustomConcurrentHashMap<K,
2174          public final void setValue(Object value) { this.value = value; }
2175      }
2176  
2177 <    static final class TerminalWeakKeyStrongValueNode
2177 >    static final class TerminalWeakKeyStrongValueNode
2178          extends WeakKeyStrongValueNode {
2179          TerminalWeakKeyStrongValueNode(int locator,
2180 <                                       Object key, Object value, CustomConcurrentHashMap cchm) {
2180 >                                       Object key, Object value,
2181 >                                       CustomConcurrentHashMap cchm) {
2182              super(locator, key, value, cchm);
2183          }
2184          public final Node getLinkage() { return null; }
2185 <        public final void setLinkage(Node r) { }
2185 >        public final void setLinkage(Node linkage) { }
2186      }
2187  
2188 <    static final class LinkedWeakKeyStrongValueNode
2188 >    static final class LinkedWeakKeyStrongValueNode
2189          extends WeakKeyStrongValueNode {
2190          volatile Node linkage;
2191          LinkedWeakKeyStrongValueNode(int locator,
2192 <                                     Object key, Object value, CustomConcurrentHashMap cchm,
2192 >                                     Object key, Object value,
2193 >                                     CustomConcurrentHashMap cchm,
2194                                       Node linkage) {
2195              super(locator, key, value, cchm);
2196              this.linkage = linkage;
2197          }
2198          public final Node getLinkage() { return linkage; }
2199 <        public final void setLinkage(Node r) { linkage = r; }
2199 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2200      }
2201  
2202 <    static final class WeakKeyStrongValueNodeFactory
2202 >    static final class WeakKeyStrongValueNodeFactory
2203          implements NodeFactory, Serializable {
2204          private static final long serialVersionUID = 7249069346764182397L;
2205          public final Node newNode(int locator,
2206 <                                  Object key, Object value,
2206 >                                  Object key, Object value,
2207                                    CustomConcurrentHashMap cchm,
2208                                    Node linkage) {
2209              if (linkage == null)
# Line 2203 | Line 2213 | public class CustomConcurrentHashMap<K,
2213                  return new LinkedWeakKeyStrongValueNode
2214                      (locator, key, value, cchm, linkage);
2215          }
2216 <    }        
2216 >    }
2217  
2218 <    static abstract class WeakKeyIntValueNode
2218 >    abstract static class WeakKeyIntValueNode
2219          extends WeakKeyNode {
2220          volatile int value;
2221          WeakKeyIntValueNode(int locator, Object key, Object value,
# Line 2214 | Line 2224 | public class CustomConcurrentHashMap<K,
2224              this.value = ((Integer)value).intValue();
2225          }
2226          public final Object getValue() { return Integer.valueOf(value); }
2227 <        public final void setValue(Object value) {
2227 >        public final void setValue(Object value) {
2228              this.value = ((Integer)value).intValue();
2229          }
2230      }
2231  
2232 <    static final class TerminalWeakKeyIntValueNode
2232 >    static final class TerminalWeakKeyIntValueNode
2233          extends WeakKeyIntValueNode {
2234          TerminalWeakKeyIntValueNode(int locator,
2235                                      Object key, Object value,
# Line 2227 | Line 2237 | public class CustomConcurrentHashMap<K,
2237              super(locator, key, value, cchm);
2238          }
2239          public final Node getLinkage() { return null; }
2240 <        public final void setLinkage(Node r) { }
2240 >        public final void setLinkage(Node linkage) { }
2241      }
2242  
2243 <    static final class LinkedWeakKeyIntValueNode
2243 >    static final class LinkedWeakKeyIntValueNode
2244          extends WeakKeyIntValueNode {
2245          volatile Node linkage;
2246          LinkedWeakKeyIntValueNode(int locator,
2247 <                                  Object key, Object value,
2247 >                                  Object key, Object value,
2248                                    CustomConcurrentHashMap cchm,
2249                                    Node linkage) {
2250              super(locator, key, value, cchm);
2251              this.linkage = linkage;
2252          }
2253          public final Node getLinkage() { return linkage; }
2254 <        public final void setLinkage(Node r) { linkage = r; }
2254 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2255      }
2256  
2257 <    static final class WeakKeyIntValueNodeFactory
2257 >    static final class WeakKeyIntValueNodeFactory
2258          implements NodeFactory, Serializable {
2259          private static final long serialVersionUID = 7249069346764182397L;
2260          public final Node newNode(int locator,
2261 <                                  Object key, Object value,
2261 >                                  Object key, Object value,
2262                                    CustomConcurrentHashMap cchm,
2263                                    Node linkage) {
2264              if (linkage == null)
# Line 2258 | Line 2268 | public class CustomConcurrentHashMap<K,
2268                  return new LinkedWeakKeyIntValueNode
2269                      (locator, key, value, cchm, linkage);
2270          }
2271 <    }        
2271 >    }
2272  
2273 <    static abstract class WeakKeyWeakValueNode
2273 >    abstract static class WeakKeyWeakValueNode
2274          extends WeakKeyNode {
2275          volatile EmbeddedWeakReference valueRef;
2276 <        WeakKeyWeakValueNode(int locator, Object key, Object value,
2276 >        WeakKeyWeakValueNode(int locator, Object key, Object value,
2277                               CustomConcurrentHashMap cchm) {
2278              super(locator, key, cchm);
2279              if (value != null)
# Line 2271 | Line 2281 | public class CustomConcurrentHashMap<K,
2281          }
2282          public final Object getValue() {
2283              EmbeddedWeakReference vr = valueRef;
2284 <            return vr == null? null : vr.get();
2284 >            return (vr == null) ? null : vr.get();
2285          }
2286          public final void setValue(Object value) {
2287              if (value == null)
# Line 2281 | Line 2291 | public class CustomConcurrentHashMap<K,
2291          }
2292      }
2293  
2294 <    static final class TerminalWeakKeyWeakValueNode
2294 >    static final class TerminalWeakKeyWeakValueNode
2295          extends WeakKeyWeakValueNode {
2296          TerminalWeakKeyWeakValueNode(int locator,
2297 <                                     Object key, Object value,
2297 >                                     Object key, Object value,
2298                                       CustomConcurrentHashMap cchm) {
2299              super(locator, key, value, cchm);
2300          }
2301          public final Node getLinkage() { return null; }
2302 <        public final void setLinkage(Node r) { }
2302 >        public final void setLinkage(Node linkage) { }
2303      }
2304  
2305 <    static final class LinkedWeakKeyWeakValueNode
2305 >    static final class LinkedWeakKeyWeakValueNode
2306          extends WeakKeyWeakValueNode {
2307          volatile Node linkage;
2308          LinkedWeakKeyWeakValueNode(int locator,
2309 <                                   Object key, Object value,
2309 >                                   Object key, Object value,
2310                                     CustomConcurrentHashMap cchm,
2311                                     Node linkage) {
2312              super(locator, key, value, cchm);
2313              this.linkage = linkage;
2314          }
2315          public final Node getLinkage() { return linkage; }
2316 <        public final void setLinkage(Node r) { linkage = r; }
2316 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2317      }
2318  
2319 <    static final class WeakKeyWeakValueNodeFactory
2319 >    static final class WeakKeyWeakValueNodeFactory
2320          implements NodeFactory, Serializable {
2321          private static final long serialVersionUID = 7249069346764182397L;
2322 <        public final Node newNode(int locator,
2323 <                                  Object key, Object value,
2322 >        public final Node newNode(int locator,
2323 >                                  Object key, Object value,
2324                                    CustomConcurrentHashMap cchm,
2325                                    Node linkage) {
2326              if (linkage == null)
# Line 2320 | Line 2330 | public class CustomConcurrentHashMap<K,
2330                  return new LinkedWeakKeyWeakValueNode
2331                      (locator, key, value, cchm, linkage);
2332          }
2333 <    }        
2333 >    }
2334  
2335  
2336 <    static abstract class WeakKeySoftValueNode
2336 >    abstract static class WeakKeySoftValueNode
2337          extends WeakKeyNode {
2338          volatile EmbeddedSoftReference valueRef;
2339 <        WeakKeySoftValueNode(int locator, Object key, Object value,
2339 >        WeakKeySoftValueNode(int locator, Object key, Object value,
2340                               CustomConcurrentHashMap cchm) {
2341              super(locator, key, cchm);
2342              if (value != null)
# Line 2334 | Line 2344 | public class CustomConcurrentHashMap<K,
2344          }
2345          public final Object getValue() {
2346              EmbeddedSoftReference vr = valueRef;
2347 <            return vr == null? null : vr.get();
2347 >            return (vr == null) ? null : vr.get();
2348          }
2349          public final void setValue(Object value) {
2350              if (value == null)
# Line 2344 | Line 2354 | public class CustomConcurrentHashMap<K,
2354          }
2355      }
2356  
2357 <    static final class TerminalWeakKeySoftValueNode
2357 >    static final class TerminalWeakKeySoftValueNode
2358          extends WeakKeySoftValueNode {
2359          TerminalWeakKeySoftValueNode(int locator,
2360 <                                     Object key, Object value,
2360 >                                     Object key, Object value,
2361                                       CustomConcurrentHashMap cchm) {
2362              super(locator, key, value, cchm);
2363          }
2364          public final Node getLinkage() { return null; }
2365 <        public final void setLinkage(Node r) { }
2365 >        public final void setLinkage(Node linkage) { }
2366      }
2367  
2368 <    static final class LinkedWeakKeySoftValueNode
2368 >    static final class LinkedWeakKeySoftValueNode
2369          extends WeakKeySoftValueNode {
2370          volatile Node linkage;
2371          LinkedWeakKeySoftValueNode(int locator,
2372 <                                   Object key, Object value,
2372 >                                   Object key, Object value,
2373                                     CustomConcurrentHashMap cchm,
2374                                     Node linkage) {
2375              super(locator, key, value, cchm);
2376              this.linkage = linkage;
2377          }
2378          public final Node getLinkage() { return linkage; }
2379 <        public final void setLinkage(Node r) { linkage = r; }
2379 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2380      }
2381  
2382 <    static final class WeakKeySoftValueNodeFactory
2382 >    static final class WeakKeySoftValueNodeFactory
2383          implements NodeFactory, Serializable {
2384          private static final long serialVersionUID = 7249069346764182397L;
2385 <        public final Node newNode(int locator,
2386 <                                  Object key, Object value,
2385 >        public final Node newNode(int locator,
2386 >                                  Object key, Object value,
2387                                    CustomConcurrentHashMap cchm,
2388                                    Node linkage) {
2389              if (linkage == null)
# Line 2383 | Line 2393 | public class CustomConcurrentHashMap<K,
2393                  return new LinkedWeakKeySoftValueNode
2394                      (locator, key, value, cchm, linkage);
2395          }
2396 <    }        
2396 >    }
2397  
2398      // Soft keys
2399  
2400 <    static abstract class SoftKeyNode extends SoftReference
2400 >    abstract static class SoftKeyNode extends SoftReference
2401          implements Node {
2402          final int locator;
2403          final CustomConcurrentHashMap cchm;
2404          SoftKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2405 <            super(key);
2405 >            super(key, getReclamationQueue());
2406              this.locator = locator;
2407              this.cchm = cchm;
2408          }
2409          public final int getLocator() { return locator; }
2410 <        public final void onReclamation() {
2410 >        public final void onReclamation() {
2411              clear();
2412              cchm.removeIfReclaimed(this);
2413          }
2414      }
2415  
2416 <    static abstract class SoftKeySelfValueNode
2416 >    abstract static class SoftKeySelfValueNode
2417          extends SoftKeyNode {
2418 <        SoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2418 >        SoftKeySelfValueNode(int locator, Object key,
2419 >                             CustomConcurrentHashMap cchm) {
2420              super(locator, key, cchm);
2421          }
2422          public final Object getValue() { return get(); }
2423          public final void setValue(Object value) { }
2424      }
2425  
2426 <    static final class TerminalSoftKeySelfValueNode
2426 >    static final class TerminalSoftKeySelfValueNode
2427          extends SoftKeySelfValueNode {
2428 <        TerminalSoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2428 >        TerminalSoftKeySelfValueNode(int locator, Object key,
2429 >                                     CustomConcurrentHashMap cchm) {
2430              super(locator, key, cchm);
2431          }
2432          public final Node getLinkage() { return null; }
2433 <        public final void setLinkage(Node r) { }
2433 >        public final void setLinkage(Node linkage) { }
2434      }
2435  
2436 <    static final class LinkedSoftKeySelfValueNode
2436 >    static final class LinkedSoftKeySelfValueNode
2437          extends SoftKeySelfValueNode {
2438          volatile Node linkage;
2439 <        LinkedSoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm,
2439 >        LinkedSoftKeySelfValueNode(int locator, Object key,
2440 >                                   CustomConcurrentHashMap cchm,
2441                                     Node linkage) {
2442              super(locator, key, cchm);
2443              this.linkage = linkage;
2444          }
2445          public final Node getLinkage() { return linkage; }
2446 <        public final void setLinkage(Node r) { linkage = r; }
2446 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2447      }
2448  
2449      static final class SoftKeySelfValueNodeFactory
2450          implements NodeFactory, Serializable {
2451          private static final long serialVersionUID = 7249069346764182397L;
2452          public final Node newNode(int locator,
2453 <                                  Object key, Object value,
2453 >                                  Object key, Object value,
2454                                    CustomConcurrentHashMap cchm,
2455                                    Node linkage) {
2456              if (linkage == null)
# Line 2447 | Line 2460 | public class CustomConcurrentHashMap<K,
2460                  return new LinkedSoftKeySelfValueNode
2461                      (locator, key, cchm, linkage);
2462          }
2463 <    }        
2463 >    }
2464  
2465  
2466 <    static abstract class SoftKeyStrongValueNode
2466 >    abstract static class SoftKeyStrongValueNode
2467          extends SoftKeyNode {
2468          volatile Object value;
2469 <        SoftKeyStrongValueNode(int locator, Object key, Object value, CustomConcurrentHashMap cchm) {
2469 >        SoftKeyStrongValueNode(int locator, Object key, Object value,
2470 >                               CustomConcurrentHashMap cchm) {
2471              super(locator, key, cchm);
2472              this.value = value;
2473          }
# Line 2461 | Line 2475 | public class CustomConcurrentHashMap<K,
2475          public final void setValue(Object value) { this.value = value; }
2476      }
2477  
2478 <    static final class TerminalSoftKeyStrongValueNode
2478 >    static final class TerminalSoftKeyStrongValueNode
2479          extends SoftKeyStrongValueNode {
2480          TerminalSoftKeyStrongValueNode(int locator,
2481 <                                       Object key, Object value, CustomConcurrentHashMap cchm) {
2481 >                                       Object key, Object value,
2482 >                                       CustomConcurrentHashMap cchm) {
2483              super(locator, key, value, cchm);
2484          }
2485          public final Node getLinkage() { return null; }
2486 <        public final void setLinkage(Node r) { }
2486 >        public final void setLinkage(Node linkage) { }
2487      }
2488  
2489 <    static final class LinkedSoftKeyStrongValueNode
2489 >    static final class LinkedSoftKeyStrongValueNode
2490          extends SoftKeyStrongValueNode {
2491          volatile Node linkage;
2492          LinkedSoftKeyStrongValueNode(int locator,
2493 <                                     Object key, Object value, CustomConcurrentHashMap cchm,
2493 >                                     Object key, Object value,
2494 >                                     CustomConcurrentHashMap cchm,
2495                                       Node linkage) {
2496              super(locator, key, value, cchm);
2497              this.linkage = linkage;
2498          }
2499          public final Node getLinkage() { return linkage; }
2500 <        public final void setLinkage(Node r) { linkage = r; }
2500 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2501      }
2502  
2503 <    static final class SoftKeyStrongValueNodeFactory
2503 >    static final class SoftKeyStrongValueNodeFactory
2504          implements NodeFactory, Serializable {
2505          private static final long serialVersionUID = 7249069346764182397L;
2506          public final Node newNode(int locator,
2507 <                                  Object key, Object value,
2507 >                                  Object key, Object value,
2508                                    CustomConcurrentHashMap cchm,
2509                                    Node linkage) {
2510              if (linkage == null)
# Line 2498 | Line 2514 | public class CustomConcurrentHashMap<K,
2514                  return new LinkedSoftKeyStrongValueNode
2515                      (locator, key, value, cchm, linkage);
2516          }
2517 <    }        
2517 >    }
2518  
2519 <    static abstract class SoftKeyIntValueNode
2519 >    abstract static class SoftKeyIntValueNode
2520          extends SoftKeyNode {
2521          volatile int value;
2522          SoftKeyIntValueNode(int locator, Object key, Object value,
# Line 2509 | Line 2525 | public class CustomConcurrentHashMap<K,
2525              this.value = ((Integer)value).intValue();
2526          }
2527          public final Object getValue() { return Integer.valueOf(value); }
2528 <        public final void setValue(Object value) {
2528 >        public final void setValue(Object value) {
2529              this.value = ((Integer)value).intValue();
2530          }
2531      }
2532  
2533 <    static final class TerminalSoftKeyIntValueNode
2533 >    static final class TerminalSoftKeyIntValueNode
2534          extends SoftKeyIntValueNode {
2535          TerminalSoftKeyIntValueNode(int locator,
2536                                      Object key, Object value,
# Line 2522 | Line 2538 | public class CustomConcurrentHashMap<K,
2538              super(locator, key, value, cchm);
2539          }
2540          public final Node getLinkage() { return null; }
2541 <        public final void setLinkage(Node r) { }
2541 >        public final void setLinkage(Node linkage) { }
2542      }
2543  
2544 <    static final class LinkedSoftKeyIntValueNode
2544 >    static final class LinkedSoftKeyIntValueNode
2545          extends SoftKeyIntValueNode {
2546          volatile Node linkage;
2547          LinkedSoftKeyIntValueNode(int locator,
2548 <                                  Object key, Object value,
2548 >                                  Object key, Object value,
2549                                    CustomConcurrentHashMap cchm,
2550                                    Node linkage) {
2551              super(locator, key, value, cchm);
2552              this.linkage = linkage;
2553          }
2554          public final Node getLinkage() { return linkage; }
2555 <        public final void setLinkage(Node r) { linkage = r; }
2555 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2556      }
2557  
2558 <    static final class SoftKeyIntValueNodeFactory
2558 >    static final class SoftKeyIntValueNodeFactory
2559          implements NodeFactory, Serializable {
2560          private static final long serialVersionUID = 7249069346764182397L;
2561          public final Node newNode(int locator,
2562 <                                  Object key, Object value,
2562 >                                  Object key, Object value,
2563                                    CustomConcurrentHashMap cchm,
2564                                    Node linkage) {
2565              if (linkage == null)
# Line 2553 | Line 2569 | public class CustomConcurrentHashMap<K,
2569                  return new LinkedSoftKeyIntValueNode
2570                      (locator, key, value, cchm, linkage);
2571          }
2572 <    }        
2572 >    }
2573  
2574 <    static abstract class SoftKeyWeakValueNode
2574 >    abstract static class SoftKeyWeakValueNode
2575          extends SoftKeyNode {
2576          volatile EmbeddedWeakReference valueRef;
2577 <        SoftKeyWeakValueNode(int locator, Object key, Object value,
2577 >        SoftKeyWeakValueNode(int locator, Object key, Object value,
2578                               CustomConcurrentHashMap cchm) {
2579              super(locator, key, cchm);
2580              if (value != null)
# Line 2566 | Line 2582 | public class CustomConcurrentHashMap<K,
2582          }
2583          public final Object getValue() {
2584              EmbeddedWeakReference vr = valueRef;
2585 <            return vr == null? null : vr.get();
2585 >            return (vr == null) ? null : vr.get();
2586          }
2587          public final void setValue(Object value) {
2588              if (value == null)
# Line 2576 | Line 2592 | public class CustomConcurrentHashMap<K,
2592          }
2593      }
2594  
2595 <    static final class TerminalSoftKeyWeakValueNode
2595 >    static final class TerminalSoftKeyWeakValueNode
2596          extends SoftKeyWeakValueNode {
2597          TerminalSoftKeyWeakValueNode(int locator,
2598 <                                     Object key, Object value,
2598 >                                     Object key, Object value,
2599                                       CustomConcurrentHashMap cchm) {
2600              super(locator, key, value, cchm);
2601          }
2602          public final Node getLinkage() { return null; }
2603 <        public final void setLinkage(Node r) { }
2603 >        public final void setLinkage(Node linkage) { }
2604      }
2605  
2606 <    static final class LinkedSoftKeyWeakValueNode
2606 >    static final class LinkedSoftKeyWeakValueNode
2607          extends SoftKeyWeakValueNode {
2608          volatile Node linkage;
2609          LinkedSoftKeyWeakValueNode(int locator,
2610 <                                   Object key, Object value,
2610 >                                   Object key, Object value,
2611                                     CustomConcurrentHashMap cchm,
2612                                     Node linkage) {
2613              super(locator, key, value, cchm);
2614              this.linkage = linkage;
2615          }
2616          public final Node getLinkage() { return linkage; }
2617 <        public final void setLinkage(Node r) { linkage = r; }
2617 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2618      }
2619  
2620 <    static final class SoftKeyWeakValueNodeFactory
2620 >    static final class SoftKeyWeakValueNodeFactory
2621          implements NodeFactory, Serializable {
2622          private static final long serialVersionUID = 7249069346764182397L;
2623 <        public final Node newNode(int locator,
2624 <                                  Object key, Object value,
2623 >        public final Node newNode(int locator,
2624 >                                  Object key, Object value,
2625                                    CustomConcurrentHashMap cchm,
2626                                    Node linkage) {
2627              if (linkage == null)
# Line 2615 | Line 2631 | public class CustomConcurrentHashMap<K,
2631                  return new LinkedSoftKeyWeakValueNode
2632                      (locator, key, value, cchm, linkage);
2633          }
2634 <    }        
2634 >    }
2635  
2636  
2637 <    static abstract class SoftKeySoftValueNode
2637 >    abstract static class SoftKeySoftValueNode
2638          extends SoftKeyNode {
2639          volatile EmbeddedSoftReference valueRef;
2640 <        SoftKeySoftValueNode(int locator, Object key, Object value,
2640 >        SoftKeySoftValueNode(int locator, Object key, Object value,
2641                               CustomConcurrentHashMap cchm) {
2642              super(locator, key, cchm);
2643              if (value != null)
# Line 2629 | Line 2645 | public class CustomConcurrentHashMap<K,
2645          }
2646          public final Object getValue() {
2647              EmbeddedSoftReference vr = valueRef;
2648 <            return vr == null? null : vr.get();
2648 >            return (vr == null) ? null : vr.get();
2649          }
2650          public final void setValue(Object value) {
2651              if (value == null)
# Line 2639 | Line 2655 | public class CustomConcurrentHashMap<K,
2655          }
2656      }
2657  
2658 <    static final class TerminalSoftKeySoftValueNode
2658 >    static final class TerminalSoftKeySoftValueNode
2659          extends SoftKeySoftValueNode {
2660          TerminalSoftKeySoftValueNode(int locator,
2661 <                                     Object key, Object value,
2661 >                                     Object key, Object value,
2662                                       CustomConcurrentHashMap cchm) {
2663              super(locator, key, value, cchm);
2664          }
2665          public final Node getLinkage() { return null; }
2666 <        public final void setLinkage(Node r) { }
2666 >        public final void setLinkage(Node linkage) { }
2667      }
2668  
2669 <    static final class LinkedSoftKeySoftValueNode
2669 >    static final class LinkedSoftKeySoftValueNode
2670          extends SoftKeySoftValueNode {
2671          volatile Node linkage;
2672          LinkedSoftKeySoftValueNode(int locator,
2673 <                                   Object key, Object value,
2673 >                                   Object key, Object value,
2674                                     CustomConcurrentHashMap cchm,
2675                                     Node linkage) {
2676              super(locator, key, value, cchm);
2677              this.linkage = linkage;
2678          }
2679          public final Node getLinkage() { return linkage; }
2680 <        public final void setLinkage(Node r) { linkage = r; }
2680 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2681      }
2682  
2683 <    static final class SoftKeySoftValueNodeFactory
2683 >    static final class SoftKeySoftValueNodeFactory
2684          implements NodeFactory, Serializable {
2685          private static final long serialVersionUID = 7249069346764182397L;
2686 <        public final Node newNode(int locator,
2687 <                                  Object key, Object value,
2686 >        public final Node newNode(int locator,
2687 >                                  Object key, Object value,
2688                                    CustomConcurrentHashMap cchm,
2689                                    Node linkage) {
2690              if (linkage == null)
# Line 2678 | Line 2694 | public class CustomConcurrentHashMap<K,
2694                  return new LinkedSoftKeySoftValueNode
2695                      (locator, key, value, cchm, linkage);
2696          }
2697 <    }        
2697 >    }
2698  
2699 <    static abstract class IntKeyNode implements Node {
2699 >    abstract static class IntKeyNode implements Node {
2700          final int key;
2701          IntKeyNode(int locator, Object key) {
2702              this.key = ((Integer)key).intValue();
# Line 2690 | Line 2706 | public class CustomConcurrentHashMap<K,
2706      }
2707  
2708  
2709 <    static abstract class IntKeySelfValueNode
2709 >    abstract static class IntKeySelfValueNode
2710          extends IntKeyNode {
2711          IntKeySelfValueNode(int locator, Object key) {
2712              super(locator, key);
# Line 2700 | Line 2716 | public class CustomConcurrentHashMap<K,
2716          public final void onReclamation() { }
2717      }
2718  
2719 <    static final class TerminalIntKeySelfValueNode
2719 >    static final class TerminalIntKeySelfValueNode
2720          extends IntKeySelfValueNode {
2721          TerminalIntKeySelfValueNode(int locator, Object key) {
2722              super(locator, key);
2723          }
2724          public final Node getLinkage() { return null; }
2725 <        public final void setLinkage(Node r) { }
2725 >        public final void setLinkage(Node linkage) { }
2726      }
2727  
2728 <    static final class LinkedIntKeySelfValueNode
2728 >    static final class LinkedIntKeySelfValueNode
2729          extends IntKeySelfValueNode {
2730          volatile Node linkage;
2731 <        LinkedIntKeySelfValueNode(int locator, Object key,
2731 >        LinkedIntKeySelfValueNode(int locator, Object key,
2732                                       Node linkage) {
2733              super(locator, key);
2734              this.linkage = linkage;
2735          }
2736          public final Node getLinkage() { return linkage; }
2737 <        public final void setLinkage(Node r) { linkage = r; }
2737 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2738      }
2739  
2740      static final class IntKeySelfValueNodeFactory
2741          implements NodeFactory, Serializable {
2742          private static final long serialVersionUID = 7249069346764182397L;
2743          public final Node newNode(int locator,
2744 <                                  Object key, Object value,
2744 >                                  Object key, Object value,
2745                                    CustomConcurrentHashMap cchm,
2746                                    Node linkage) {
2747              if (linkage == null)
# Line 2735 | Line 2751 | public class CustomConcurrentHashMap<K,
2751                  return new LinkedIntKeySelfValueNode
2752                      (locator, key, linkage);
2753          }
2754 <    }        
2754 >    }
2755  
2756 <    static abstract class IntKeyStrongValueNode
2756 >    abstract static class IntKeyStrongValueNode
2757          extends IntKeyNode {
2758          volatile Object value;
2759          IntKeyStrongValueNode(int locator, Object key, Object value) {
# Line 2749 | Line 2765 | public class CustomConcurrentHashMap<K,
2765          public final void onReclamation() { }
2766      }
2767  
2768 <    static final class TerminalIntKeyStrongValueNode
2768 >    static final class TerminalIntKeyStrongValueNode
2769          extends IntKeyStrongValueNode {
2770          TerminalIntKeyStrongValueNode(int locator,
2771                                           Object key, Object value) {
2772              super(locator, key, value);
2773          }
2774          public final Node getLinkage() { return null; }
2775 <        public final void setLinkage(Node r) { }
2775 >        public final void setLinkage(Node linkage) { }
2776      }
2777  
2778 <    static final class LinkedIntKeyStrongValueNode
2778 >    static final class LinkedIntKeyStrongValueNode
2779          extends IntKeyStrongValueNode {
2780          volatile Node linkage;
2781          LinkedIntKeyStrongValueNode(int locator,
2782 <                                       Object key, Object value,
2782 >                                       Object key, Object value,
2783                                         Node linkage) {
2784              super(locator, key, value);
2785              this.linkage = linkage;
2786          }
2787          public final Node getLinkage() { return linkage; }
2788 <        public final void setLinkage(Node r) { linkage = r; }
2788 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2789      }
2790  
2791 <    static final class IntKeyStrongValueNodeFactory
2791 >    static final class IntKeyStrongValueNodeFactory
2792          implements NodeFactory, Serializable {
2793          private static final long serialVersionUID = 7249069346764182397L;
2794          public final Node newNode(int locator,
2795 <                                  Object key, Object value,
2795 >                                  Object key, Object value,
2796                                    CustomConcurrentHashMap cchm,
2797                                    Node linkage) {
2798              if (linkage == null)
# Line 2786 | Line 2802 | public class CustomConcurrentHashMap<K,
2802                  return new LinkedIntKeyStrongValueNode
2803                      (locator, key, value, linkage);
2804          }
2805 <    }        
2805 >    }
2806  
2807 <    static abstract class IntKeyIntValueNode
2807 >    abstract static class IntKeyIntValueNode
2808          extends IntKeyNode {
2809          volatile int value;
2810          IntKeyIntValueNode(int locator, Object key, Object value) {
# Line 2796 | Line 2812 | public class CustomConcurrentHashMap<K,
2812              this.value = ((Integer)value).intValue();
2813          }
2814          public final Object getValue() { return Integer.valueOf(value); }
2815 <        public final void setValue(Object value) {
2815 >        public final void setValue(Object value) {
2816              this.value = ((Integer)value).intValue();
2817          }
2818          public final void onReclamation() { }
2819      }
2820  
2821 <    static final class TerminalIntKeyIntValueNode
2821 >    static final class TerminalIntKeyIntValueNode
2822          extends IntKeyIntValueNode {
2823          TerminalIntKeyIntValueNode(int locator,
2824                                           Object key, Object value) {
2825              super(locator, key, value);
2826          }
2827          public final Node getLinkage() { return null; }
2828 <        public final void setLinkage(Node r) { }
2828 >        public final void setLinkage(Node linkage) { }
2829      }
2830  
2831 <    static final class LinkedIntKeyIntValueNode
2831 >    static final class LinkedIntKeyIntValueNode
2832          extends IntKeyIntValueNode {
2833          volatile Node linkage;
2834          LinkedIntKeyIntValueNode(int locator,
2835 <                                       Object key, Object value,
2835 >                                       Object key, Object value,
2836                                         Node linkage) {
2837              super(locator, key, value);
2838              this.linkage = linkage;
2839          }
2840          public final Node getLinkage() { return linkage; }
2841 <        public final void setLinkage(Node r) { linkage = r; }
2841 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2842      }
2843  
2844 <    static final class IntKeyIntValueNodeFactory
2844 >    static final class IntKeyIntValueNodeFactory
2845          implements NodeFactory, Serializable {
2846          private static final long serialVersionUID = 7249069346764182397L;
2847          public final Node newNode(int locator,
2848 <                                  Object key, Object value,
2848 >                                  Object key, Object value,
2849                                    CustomConcurrentHashMap cchm,
2850                                    Node linkage) {
2851              if (linkage == null)
# Line 2839 | Line 2855 | public class CustomConcurrentHashMap<K,
2855                  return new LinkedIntKeyIntValueNode
2856                      (locator, key, value, linkage);
2857          }
2858 <    }        
2858 >    }
2859  
2860 <    static abstract class IntKeyWeakValueNode
2860 >    abstract static class IntKeyWeakValueNode
2861          extends IntKeyNode {
2862          volatile EmbeddedWeakReference valueRef;
2863          final CustomConcurrentHashMap cchm;
2864 <        IntKeyWeakValueNode(int locator, Object key, Object value,
2864 >        IntKeyWeakValueNode(int locator, Object key, Object value,
2865                                 CustomConcurrentHashMap cchm) {
2866              super(locator, key);
2867              this.cchm = cchm;
# Line 2857 | Line 2873 | public class CustomConcurrentHashMap<K,
2873          }
2874          public final Object getValue() {
2875              EmbeddedWeakReference vr = valueRef;
2876 <            return vr == null? null : vr.get();
2876 >            return (vr == null) ? null : vr.get();
2877          }
2878          public final void setValue(Object value) {
2879              if (value == null)
# Line 2867 | Line 2883 | public class CustomConcurrentHashMap<K,
2883          }
2884      }
2885  
2886 <    static final class TerminalIntKeyWeakValueNode
2886 >    static final class TerminalIntKeyWeakValueNode
2887          extends IntKeyWeakValueNode {
2888          TerminalIntKeyWeakValueNode(int locator,
2889 <                                       Object key, Object value,
2889 >                                       Object key, Object value,
2890                                         CustomConcurrentHashMap cchm) {
2891              super(locator, key, value, cchm);
2892          }
2893          public final Node getLinkage() { return null; }
2894 <        public final void setLinkage(Node r) { }
2894 >        public final void setLinkage(Node linkage) { }
2895      }
2896  
2897 <    static final class LinkedIntKeyWeakValueNode
2897 >    static final class LinkedIntKeyWeakValueNode
2898          extends IntKeyWeakValueNode {
2899          volatile Node linkage;
2900          LinkedIntKeyWeakValueNode(int locator,
2901 <                                     Object key, Object value,
2901 >                                     Object key, Object value,
2902                                       CustomConcurrentHashMap cchm,
2903                                       Node linkage) {
2904              super(locator, key, value, cchm);
2905              this.linkage = linkage;
2906          }
2907          public final Node getLinkage() { return linkage; }
2908 <        public final void setLinkage(Node r) { linkage = r; }
2908 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2909      }
2910  
2911 <    static final class IntKeyWeakValueNodeFactory
2911 >    static final class IntKeyWeakValueNodeFactory
2912          implements NodeFactory, Serializable {
2913          private static final long serialVersionUID = 7249069346764182397L;
2914 <        public final Node newNode(int locator,
2915 <                                  Object key, Object value,
2914 >        public final Node newNode(int locator,
2915 >                                  Object key, Object value,
2916                                    CustomConcurrentHashMap cchm,
2917                                    Node linkage) {
2918              if (linkage == null)
# Line 2906 | Line 2922 | public class CustomConcurrentHashMap<K,
2922                  return new LinkedIntKeyWeakValueNode
2923                      (locator, key, value, cchm, linkage);
2924          }
2925 <    }        
2925 >    }
2926  
2927  
2928 <    static abstract class IntKeySoftValueNode
2928 >    abstract static class IntKeySoftValueNode
2929          extends IntKeyNode {
2930          volatile EmbeddedSoftReference valueRef;
2931          final CustomConcurrentHashMap cchm;
2932 <        IntKeySoftValueNode(int locator, Object key, Object value,
2933 <                               CustomConcurrentHashMap cchm) {
2932 >        IntKeySoftValueNode(int locator, Object key, Object value,
2933 >                            CustomConcurrentHashMap cchm) {
2934              super(locator, key);
2935              this.cchm = cchm;
2936              if (value != null)
# Line 2925 | Line 2941 | public class CustomConcurrentHashMap<K,
2941          }
2942          public final Object getValue() {
2943              EmbeddedSoftReference vr = valueRef;
2944 <            return vr == null? null : vr.get();
2944 >            return (vr == null) ? null : vr.get();
2945          }
2946          public final void setValue(Object value) {
2947              if (value == null)
# Line 2935 | Line 2951 | public class CustomConcurrentHashMap<K,
2951          }
2952      }
2953  
2954 <    static final class TerminalIntKeySoftValueNode
2954 >    static final class TerminalIntKeySoftValueNode
2955          extends IntKeySoftValueNode {
2956          TerminalIntKeySoftValueNode(int locator,
2957 <                                       Object key, Object value,
2957 >                                       Object key, Object value,
2958                                         CustomConcurrentHashMap cchm) {
2959              super(locator, key, value, cchm);
2960          }
2961          public final Node getLinkage() { return null; }
2962 <        public final void setLinkage(Node r) { }
2962 >        public final void setLinkage(Node linkage) { }
2963      }
2964  
2965 <    static final class LinkedIntKeySoftValueNode
2965 >    static final class LinkedIntKeySoftValueNode
2966          extends IntKeySoftValueNode {
2967          volatile Node linkage;
2968          LinkedIntKeySoftValueNode(int locator,
2969 <                                     Object key, Object value,
2969 >                                     Object key, Object value,
2970                                       CustomConcurrentHashMap cchm,
2971                                       Node linkage) {
2972              super(locator, key, value, cchm);
2973              this.linkage = linkage;
2974          }
2975          public final Node getLinkage() { return linkage; }
2976 <        public final void setLinkage(Node r) { linkage = r; }
2976 >        public final void setLinkage(Node linkage) { this.linkage = linkage; }
2977      }
2978  
2979 <    static final class IntKeySoftValueNodeFactory
2979 >    static final class IntKeySoftValueNodeFactory
2980          implements NodeFactory, Serializable {
2981          private static final long serialVersionUID = 7249069346764182397L;
2982 <        public final Node newNode(int locator,
2983 <                                  Object key, Object value,
2982 >        public final Node newNode(int locator,
2983 >                                  Object key, Object value,
2984                                    CustomConcurrentHashMap cchm,
2985                                    Node linkage) {
2986              if (linkage == null)
# Line 2974 | Line 2990 | public class CustomConcurrentHashMap<K,
2990                  return new LinkedIntKeySoftValueNode
2991                      (locator, key, value, cchm, linkage);
2992          }
2993 <    }        
2993 >    }
2994  
2995  
2996  
2997      // Temporary Unsafe mechanics for preliminary release
2998  
2999 <    static final Unsafe _unsafe;
2999 >    static final Unsafe UNSAFE;
3000      static final long tableBase;
3001      static final int tableShift;
3002      static final long segmentsBase;
3003      static final int segmentsShift;
3004  
2989    private static Unsafe getUnsafe() throws Throwable {
2990        try {
2991            return Unsafe.getUnsafe();
2992        } catch (SecurityException se) {
2993            try {
2994                return java.security.AccessController.doPrivileged
2995                    (new java.security.PrivilegedExceptionAction<Unsafe>() {
2996                        public Unsafe run() throws Exception {
2997                            return getUnsafePrivileged();
2998                        }});
2999            } catch (java.security.PrivilegedActionException e) {
3000                throw e.getCause();
3001            }
3002        }
3003    }
3004
3005    private static Unsafe getUnsafePrivileged()
3006        throws NoSuchFieldException, IllegalAccessException {
3007        Field f = Unsafe.class.getDeclaredField("theUnsafe");
3008        f.setAccessible(true);
3009        return (Unsafe) f.get(null);
3010    }
3011
3005      static {
3006          try {
3007 <            _unsafe = getUnsafe();
3008 <            tableBase = _unsafe.arrayBaseOffset(Node[].class);
3009 <            int s = _unsafe.arrayIndexScale(Node[].class);
3010 <            if ((s & (s-1)) != 0)
3007 >            UNSAFE = getUnsafe();
3008 >            tableBase = UNSAFE.arrayBaseOffset(Node[].class);
3009 >            int scale = UNSAFE.arrayIndexScale(Node[].class);
3010 >            if ((scale & (scale - 1)) != 0)
3011                  throw new Error("data type scale not a power of two");
3012 <            tableShift = 31 - Integer.numberOfLeadingZeros(s);
3013 <            segmentsBase = _unsafe.arrayBaseOffset(Segment[].class);
3014 <            s = _unsafe.arrayIndexScale(Segment[].class);
3015 <            if ((s & (s-1)) != 0)
3012 >            tableShift = 31 - Integer.numberOfLeadingZeros(scale);
3013 >            segmentsBase = UNSAFE.arrayBaseOffset(Segment[].class);
3014 >            scale = UNSAFE.arrayIndexScale(Segment[].class);
3015 >            if ((scale & (scale - 1)) != 0)
3016                  throw new Error("data type scale not a power of two");
3017 <            segmentsShift = 31 - Integer.numberOfLeadingZeros(s);
3017 >            segmentsShift = 31 - Integer.numberOfLeadingZeros(scale);
3018          } catch (Throwable e) {
3019              throw new RuntimeException("Could not initialize intrinsics", e);
3020          }
3021      }
3022  
3023      // Fenced store into segment table array. Unneeded when we have Fences
3024 <    static final  void storeNode(Node[] table,
3025 <                                 int i, Node r) {
3026 <        _unsafe.putOrderedObject(table, (i << tableShift) + tableBase, r);
3024 >    static final void storeNode(Node[] table,
3025 >                                int i, Node r) {
3026 >        long nodeOffset = ((long) i << tableShift) + tableBase;
3027 >        UNSAFE.putOrderedObject(table, nodeOffset, r);
3028      }
3029  
3030 <    static final  void storeSegment(Segment[] segs,
3031 <                                    int i, Segment s) {
3032 <        _unsafe.putOrderedObject(segs, (i << segmentsShift) + segmentsBase, s);
3030 >    static final void storeSegment(Segment[] segs,
3031 >                                   int i, Segment s) {
3032 >        long segmentOffset = ((long) i << segmentsShift) + segmentsBase;
3033 >        UNSAFE.putOrderedObject(segs, segmentOffset, s);
3034      }
3035  
3036 <
3036 >    /**
3037 >     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
3038 >     * Replace with a simple call to Unsafe.getUnsafe when integrating
3039 >     * into a jdk.
3040 >     *
3041 >     * @return a sun.misc.Unsafe
3042 >     */
3043 >    private static sun.misc.Unsafe getUnsafe() {
3044 >        try {
3045 >            return sun.misc.Unsafe.getUnsafe();
3046 >        } catch (SecurityException tryReflectionInstead) {}
3047 >        try {
3048 >            return java.security.AccessController.doPrivileged
3049 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
3050 >                public sun.misc.Unsafe run() throws Exception {
3051 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
3052 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
3053 >                        f.setAccessible(true);
3054 >                        Object x = f.get(null);
3055 >                        if (k.isInstance(x))
3056 >                            return k.cast(x);
3057 >                    }
3058 >                    throw new NoSuchFieldError("the Unsafe");
3059 >                }});
3060 >        } catch (java.security.PrivilegedActionException e) {
3061 >            throw new RuntimeException("Could not initialize intrinsics",
3062 >                                       e.getCause());
3063 >        }
3064 >    }
3065   }
3043

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines