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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines