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.9 by jsr166, Sun Nov 22 19:09:19 2009 UTC vs.
Revision 1.26 by jsr166, Wed Jan 16 00:51:11 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.
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>
# Line 56 | Line 56 | import sun.misc.Unsafe;
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;
59 > *             return (x instanceof Person) ? ((Person)x).name.hashCode() : 0;
60   *          }
61   *        },
62   *      STRONG, EQUALS, 0);
# Line 72 | Line 72 | import sun.misc.Unsafe;
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
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)</code> may
86 < * return true even if <code>value</code> is no longer available upon
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 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 224 | Line 224 | public class CustomConcurrentHashMap<K,
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
247 >     * current value to a new value, or {@code null} if there is
248       * no mapping
249       */
250      public static interface RemappingFunction<K, V> {
# Line 320 | 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 544 | Line 544 | public class CustomConcurrentHashMap<K,
544      }
545  
546      /**
547 <     * Creates a new CustomConcurrentHashMap with the given parameters
547 >     * Creates a new CustomConcurrentHashMap with the given parameters.
548       * @param keyStrength the strength for keys
549       * @param keyEquivalence the Equivalence to use for keys
550       * @param valueStrength the strength for values
# Line 573 | Line 573 | public class CustomConcurrentHashMap<K,
573  
574      /**
575       * Returns a new map using Integer keys and the given value
576 <     * parameters
576 >     * parameters.
577       * @param valueStrength the strength for values
578       * @param valueEquivalence the Equivalence to use for values
579       * @param expectedSize an estimate of the number of elements
# Line 591 | Line 591 | public class CustomConcurrentHashMap<K,
591      }
592  
593      /**
594 <     * Returns a new map using the given key parameters and Integer values
594 >     * Returns a new map using the given key parameters and Integer values.
595       * @param keyStrength the strength for keys
596       * @param keyEquivalence the Equivalence to use for keys
597       * @param expectedSize an estimate of the number of elements
# Line 609 | Line 609 | public class CustomConcurrentHashMap<K,
609      }
610  
611      /**
612 <     * Returns a new map using Integer keys and values
612 >     * Returns a new map using Integer keys and values.
613       * @param expectedSize an estimate of the number of elements
614       * that will be held in the map. If no estimate is known,
615       * zero is an acceptable value.
# Line 623 | Line 623 | public class CustomConcurrentHashMap<K,
623      }
624  
625      /**
626 <     * Returns the segment for traversing table for key with given hash
626 >     * Returns the segment for traversing table for key with given hash.
627       * @param hash the hash code for the key
628       * @return the segment, or null if not yet initialized
629       */
# Line 642 | Line 642 | public class CustomConcurrentHashMap<K,
642          int index = (hash >>> SEGMENT_SHIFT) & SEGMENT_MASK;
643          Segment seg = segs[index];
644          if (seg == null) {
645 <            synchronized(segs) {
645 >            synchronized (segs) {
646                  seg = segs[index];
647                  if (seg == null) {
648                      seg = new Segment();
# Line 656 | Line 656 | public class CustomConcurrentHashMap<K,
656      }
657  
658      /**
659 <     * Returns node for key, or null if none
659 >     * Returns node for key, or null if none.
660       */
661      final Node findNode(Object key, int hash, Segment seg) {
662          if (seg != null) {
# Line 678 | Line 678 | public class CustomConcurrentHashMap<K,
678      }
679  
680      /**
681 <     * Returns <tt>true</tt> if this map contains a key equivalent to
681 >     * Returns {@code true} if this map contains a key equivalent to
682       * the given key with respect to this map's key Equivalence.
683       *
684       * @param  key   possible key
685 <     * @return <tt>true</tt> if this map contains the specified key
685 >     * @return {@code true} if this map contains the specified key
686       * @throws NullPointerException if the specified key is null
687       */
688      public boolean containsKey(Object key) {
# Line 697 | Line 697 | public class CustomConcurrentHashMap<K,
697      /**
698       * Returns the value associated with a key equivalent to the given
699       * key with respect to this map's key Equivalence, or {@code null}
700 <     * if no such mapping exists
700 >     * if no such mapping exists.
701       *
702       * @param  key   possible key
703 <     * @return the value associated with the key or <tt>null</tt> if
703 >     * @return the value associated with the key or {@code null} if
704       * there is no mapping.
705       * @throws NullPointerException if the specified key is null
706       */
# Line 752 | Line 752 | public class CustomConcurrentHashMap<K,
752       *
753       * @param key key with which the specified value is to be associated
754       * @param value value to be associated with the specified key
755 <     * @return the previous value associated with <tt>key</tt>, or
756 <     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
755 >     * @return the previous value associated with {@code key}, or
756 >     *         {@code null} if there was no mapping for {@code key}
757       * @throws NullPointerException if the specified key or value is null
758       */
759      public V put(K key, V value) {
# Line 764 | Line 764 | public class CustomConcurrentHashMap<K,
764       * {@inheritDoc}
765       *
766       * @return the previous value associated with the specified key,
767 <     *         or <tt>null</tt> if there was no mapping for the key
767 >     *         or {@code null} if there was no mapping for the key
768       * @throws NullPointerException if the specified key or value is null
769       */
770      public V putIfAbsent(K key, V value) {
# Line 813 | Line 813 | public class CustomConcurrentHashMap<K,
813       * {@inheritDoc}
814       *
815       * @return the previous value associated with the specified key,
816 <     *         or <tt>null</tt> if there was no mapping for the key
816 >     *         or {@code null} if there was no mapping for the key
817       * @throws NullPointerException if the specified key or value is null
818       */
819      public boolean replace(K key, V oldValue, V newValue) {
# Line 845 | Line 845 | public class CustomConcurrentHashMap<K,
845       * Removes the mapping for the specified key.
846       *
847       * @param  key the key to remove
848 <     * @return the previous value associated with <tt>key</tt>, or
849 <     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
848 >     * @return the previous value associated with {@code key}, or
849 >     *         {@code null} if there was no mapping for {@code key}
850       * @throws NullPointerException if the specified key is null
851       */
852      public V remove(Object key) {
# Line 942 | Line 942 | public class CustomConcurrentHashMap<K,
942      }
943  
944      /**
945 <     * Remove node if its key or value are null
945 >     * Removes node if its key or value are null.
946       */
947      final void removeIfReclaimed(Node r) {
948          int hash = r.getLocator();
# Line 979 | Line 979 | public class CustomConcurrentHashMap<K,
979      }
980  
981      /**
982 <     * Returns <tt>true</tt> if this map contains no key-value mappings.
982 >     * Returns {@code true} if this map contains no key-value mappings.
983       *
984 <     * @return <tt>true</tt> if this map contains no key-value mappings
984 >     * @return {@code true} if this map contains no key-value mappings
985       */
986      public final boolean isEmpty() {
987          final Segment[] segs = this.segments;
# Line 997 | Line 997 | public class CustomConcurrentHashMap<K,
997  
998      /**
999       * Returns the number of key-value mappings in this map.  If the
1000 <     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
1001 <     * <tt>Integer.MAX_VALUE</tt>.
1000 >     * map contains more than {@code Integer.MAX_VALUE} elements, returns
1001 >     * {@code Integer.MAX_VALUE}.
1002       *
1003       * @return the number of key-value mappings in this map
1004       */
# Line 1010 | Line 1010 | public class CustomConcurrentHashMap<K,
1010              if (seg != null && seg.getTableForTraversal() != null)
1011                  sum += seg.count;
1012          }
1013 <        return sum >= Integer.MAX_VALUE? Integer.MAX_VALUE : (int)sum;
1013 >        return (sum >= Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) sum;
1014      }
1015  
1016      /**
1017 <     * Returns <tt>true</tt> if this map maps one or more keys to a
1017 >     * Returns {@code true} if this map maps one or more keys to a
1018       * value equivalent to the given value with respect to this map's
1019       * value Equivalence.  Note: This method requires a full internal
1020       * traversal of the hash table, and so is much slower than method
1021 <     * <tt>containsKey</tt>.
1021 >     * {@code containsKey}.
1022       *
1023       * @param value value whose presence in this map is to be tested
1024 <     * @return <tt>true</tt> if this map maps one or more keys to the
1024 >     * @return {@code true} if this map maps one or more keys to the
1025       *         specified value
1026       * @throws NullPointerException if the specified value is null
1027       */
# Line 1069 | Line 1069 | public class CustomConcurrentHashMap<K,
1069      /**
1070       * If the specified key is not already associated with a value,
1071       * computes its value using the given mappingFunction, and if
1072 <     * nonnull, enters it into the map.  This is equivalent to
1072 >     * non-null, enters it into the map.  This is equivalent to
1073       *
1074       * <pre>
1075       *   if (map.containsKey(key))
# Line 1091 | Line 1091 | public class CustomConcurrentHashMap<K,
1091       * @param key key with which the specified value is to be associated
1092       * @param mappingFunction the function to compute a value
1093       * @return the current (existing or computed) value associated with
1094 <     *         the specified key, or <tt>null</tt> if the computation
1095 <     *         returned <tt>null</tt>.
1094 >     *         the specified key, or {@code null} if the computation
1095 >     *         returned {@code null}.
1096       * @throws NullPointerException if the specified key or mappingFunction
1097       *         is null,
1098       * @throws RuntimeException or Error if the mappingFunction does so,
# Line 1158 | Line 1158 | public class CustomConcurrentHashMap<K,
1158       * <pre>
1159       * map.compute(word, new RemappingFunction&lt;String,Integer&gt;() {
1160       *   public Integer remap(String k, Integer v) {
1161 <     *     return v == null? 1 : v + 1;
1161 >     *     return (v == null) ? 1 : v + 1;
1162       *   }});
1163       * </pre>
1164       *
1165       * @param key key with which the specified value is to be associated
1166       * @param remappingFunction the function to compute a value
1167       * @return the updated value or
1168 <     *         <tt>null</tt> if the computation returned <tt>null</tt>
1168 >     *         {@code null} if the computation returned {@code null}
1169       * @throws NullPointerException if the specified key or remappingFunction
1170       *         is null,
1171       * @throws RuntimeException or Error if the remappingFunction does so,
# Line 1414 | Line 1414 | public class CustomConcurrentHashMap<K,
1414              if (!(o instanceof Map.Entry))
1415                  return false;
1416              Map.Entry<?,?> e = (Map.Entry<?,?>)o;
1417 <            return CustomConcurrentHashMap.this.remove(e.getKey(), e.getValue());
1417 >            return CustomConcurrentHashMap.this.remove(e.getKey(),
1418 >                                                       e.getValue());
1419          }
1420          public int size() {
1421              return CustomConcurrentHashMap.this.size();
# Line 1432 | Line 1433 | public class CustomConcurrentHashMap<K,
1433       * The set is backed by the map, so changes to the map are
1434       * reflected in the set, and vice-versa.  The set supports element
1435       * removal, which removes the corresponding mapping from this map,
1436 <     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1437 <     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
1438 <     * operations.  It does not support the <tt>add</tt> or
1439 <     * <tt>addAll</tt> operations.
1436 >     * via the {@code Iterator.remove}, {@code Set.remove},
1437 >     * {@code removeAll}, {@code retainAll}, and {@code clear}
1438 >     * operations.  It does not support the {@code add} or
1439 >     * {@code addAll} operations.
1440       *
1441 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1441 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1442       * that will never throw {@link ConcurrentModificationException},
1443       * and guarantees to traverse elements as they existed upon
1444       * construction of the iterator, and may (but is not guaranteed to)
# Line 1453 | Line 1454 | public class CustomConcurrentHashMap<K,
1454       * The collection is backed by the map, so changes to the map are
1455       * reflected in the collection, and vice-versa.  The collection
1456       * supports element removal, which removes the corresponding
1457 <     * mapping from this map, via the <tt>Iterator.remove</tt>,
1458 <     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1459 <     * <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not
1460 <     * support the <tt>add</tt> or <tt>addAll</tt> operations.
1457 >     * mapping from this map, via the {@code Iterator.remove},
1458 >     * {@code Collection.remove}, {@code removeAll},
1459 >     * {@code retainAll}, and {@code clear} operations.  It does not
1460 >     * support the {@code add} or {@code addAll} operations.
1461       *
1462 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1462 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1463       * that will never throw {@link ConcurrentModificationException},
1464       * and guarantees to traverse elements as they existed upon
1465       * construction of the iterator, and may (but is not guaranteed to)
# Line 1474 | Line 1475 | public class CustomConcurrentHashMap<K,
1475       * The set is backed by the map, so changes to the map are
1476       * reflected in the set, and vice-versa.  The set supports element
1477       * removal, which removes the corresponding mapping from the map,
1478 <     * via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
1479 <     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
1480 <     * operations.  It does not support the <tt>add</tt> or
1481 <     * <tt>addAll</tt> operations.
1478 >     * via the {@code Iterator.remove}, {@code Set.remove},
1479 >     * {@code removeAll}, {@code retainAll}, and {@code clear}
1480 >     * operations.  It does not support the {@code add} or
1481 >     * {@code addAll} operations.
1482       *
1483 <     * <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
1483 >     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1484       * that will never throw {@link ConcurrentModificationException},
1485       * and guarantees to traverse elements as they existed upon
1486       * construction of the iterator, and may (but is not guaranteed to)
# Line 1494 | Line 1495 | public class CustomConcurrentHashMap<K,
1495  
1496      /**
1497       * Compares the specified object with this map for equality.
1498 <     * Returns <tt>true</tt> if the given object is also a map of the
1498 >     * Returns {@code true} if the given object is also a map of the
1499       * same size, holding keys that are equal using this Map's key
1500       * Equivalence, and which map to values that are equal according
1501       * to this Map's value equivalence.
1502       *
1503       * @param o object to be compared for equality with this map
1504 <     * @return <tt>true</tt> if the specified object is equal to this map
1504 >     * @return {@code true} if the specified object is equal to this map
1505       */
1506      public boolean equals(Object o) {
1507          if (o == this)
# Line 1537 | Line 1538 | public class CustomConcurrentHashMap<K,
1538  
1539      /**
1540       * Returns the sum of the hash codes of each entry in this map's
1541 <     * <tt>entrySet()</tt> view, which in turn are the hash codes
1541 >     * {@code entrySet()} view, which in turn are the hash codes
1542       * computed using key and value Equivalences for this Map.
1543       * @return the hash code
1544       */
# Line 1550 | Line 1551 | public class CustomConcurrentHashMap<K,
1551      }
1552  
1553      /**
1554 <     * Save the state of the instance to a stream (i.e., serialize
1555 <     * it).
1554 >     * Saves the state of the instance to a stream (i.e., serializes it).
1555 >     *
1556       * @param s the stream
1557       * @serialData
1558       * the key (Object) and value (Object)
1559       * for each key-value mapping, followed by a null pair.
1560       * The key-value mappings are emitted in no particular order.
1561       */
1562 <    private void writeObject(java.io.ObjectOutputStream s) throws IOException  {
1562 >    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1563          s.defaultWriteObject();
1564          for (Map.Entry<K,V> e : entrySet()) {
1565              s.writeObject(e.getKey());
# Line 1569 | Line 1570 | public class CustomConcurrentHashMap<K,
1570      }
1571  
1572      /**
1573 <     * Reconstitute the instance from a stream (i.e., deserialize it).
1573 >     * Reconstitutes the instance from a stream (that is, deserializes it).
1574       * @param s the stream
1575       */
1576      private void readObject(java.io.ObjectInputStream s)
1577 <        throws IOException, ClassNotFoundException  {
1577 >        throws IOException, ClassNotFoundException {
1578          s.defaultReadObject();
1579          this.segments = (Segment[])(new Segment[NSEGMENTS]);
1580          for (;;) {
# Line 1587 | Line 1588 | public class CustomConcurrentHashMap<K,
1588  
1589      /**
1590       * A hash-based set with properties identical to those of
1591 <     * <code>Collections.newSetFromMap</code> applied to a
1592 <     * <code>CustomConcurrentHashMap</code>, but possibly more
1591 >     * {@code Collections.newSetFromMap} applied to a
1592 >     * {@code CustomConcurrentHashMap}, but possibly more
1593       * space-efficient.  The set does not permit null elements. The
1594       * set is serializable; however, serializing a set that uses soft
1595       * or weak references can give unpredictable results.
# Line 1599 | Line 1600 | public class CustomConcurrentHashMap<K,
1600          final CustomConcurrentHashMap<K,K> cchm;
1601  
1602          /**
1603 <         * Creates a set with the given parameters
1603 >         * Creates a set with the given parameters.
1604           * @param strength the strength of elements
1605           * @param equivalence the Equivalence to use
1606           * @param expectedSize an estimate of the number of elements
# Line 1620 | Line 1621 | public class CustomConcurrentHashMap<K,
1621           * exists, else adds and returns the given element.
1622           *
1623           * @param e the element
1624 <         * @return e, or an element equivalent to e.
1624 >         * @return e, or an element equivalent to e
1625           */
1626          public K intern(K e) {
1627              K oldElement = cchm.doPut(e, e, true);
# Line 1628 | Line 1629 | public class CustomConcurrentHashMap<K,
1629          }
1630  
1631          /**
1632 <         * Returns <tt>true</tt> if this set contains an
1632 >         * Returns {@code true} if this set contains an
1633           * element equivalent to the given element with respect
1634           * to this set's Equivalence.
1635           * @param o element whose presence in this set is to be tested
1636 <         * @return <tt>true</tt> if this set contains the specified element
1636 >         * @return {@code true} if this set contains the specified element
1637           */
1638          public boolean contains(Object o) {
1639              return cchm.containsKey(o);
# Line 1655 | Line 1656 | public class CustomConcurrentHashMap<K,
1656           * respect to this set's Equivalence.
1657           *
1658           * @param e element to be added to this set
1659 <         * @return <tt>true</tt> if this set did not already contain
1659 >         * @return {@code true} if this set did not already contain
1660           * the specified element
1661           */
1662          public boolean add(K e) {
# Line 1667 | Line 1668 | public class CustomConcurrentHashMap<K,
1668           * respect to this set's Equivalence, if one is present.
1669           *
1670           * @param o object to be removed from this set, if present
1671 <         * @return <tt>true</tt> if the set contained the specified element
1671 >         * @return {@code true} if the set contained the specified element
1672           */
1673          public boolean remove(Object o) {
1674              return cchm.remove(o) != null;
1675          }
1676  
1677          /**
1678 <         * Returns <tt>true</tt> if this set contains no elements.
1678 >         * Returns {@code true} if this set contains no elements.
1679           *
1680 <         * @return <tt>true</tt> if this set contains no elements
1680 >         * @return {@code true} if this set contains no elements
1681           */
1682          public boolean isEmpty() {
1683              return cchm.isEmpty();
# Line 1975 | Line 1976 | public class CustomConcurrentHashMap<K,
1976          }
1977          public final Object getValue() {
1978              EmbeddedWeakReference vr = valueRef;
1979 <            return vr == null? null : vr.get();
1979 >            return (vr == null) ? null : vr.get();
1980          }
1981          public final void setValue(Object value) {
1982              if (value == null)
# Line 2043 | Line 2044 | public class CustomConcurrentHashMap<K,
2044          }
2045          public final Object getValue() {
2046              EmbeddedSoftReference vr = valueRef;
2047 <            return vr == null? null : vr.get();
2047 >            return (vr == null) ? null : vr.get();
2048          }
2049          public final void setValue(Object value) {
2050              if (value == null)
# Line 2101 | Line 2102 | public class CustomConcurrentHashMap<K,
2102          final int locator;
2103          final CustomConcurrentHashMap cchm;
2104          WeakKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2105 <            super(key);
2105 >            super(key, getReclamationQueue());
2106              this.locator = locator;
2107              this.cchm = cchm;
2108          }
# Line 2114 | Line 2115 | public class CustomConcurrentHashMap<K,
2115  
2116      static abstract class WeakKeySelfValueNode
2117          extends WeakKeyNode {
2118 <        WeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2118 >        WeakKeySelfValueNode(int locator, Object key,
2119 >                             CustomConcurrentHashMap cchm) {
2120              super(locator, key, cchm);
2121          }
2122          public final Object getValue() { return get(); }
# Line 2123 | Line 2125 | public class CustomConcurrentHashMap<K,
2125  
2126      static final class TerminalWeakKeySelfValueNode
2127          extends WeakKeySelfValueNode {
2128 <        TerminalWeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2128 >        TerminalWeakKeySelfValueNode(int locator, Object key,
2129 >                                     CustomConcurrentHashMap cchm) {
2130              super(locator, key, cchm);
2131          }
2132          public final Node getLinkage() { return null; }
# Line 2133 | Line 2136 | public class CustomConcurrentHashMap<K,
2136      static final class LinkedWeakKeySelfValueNode
2137          extends WeakKeySelfValueNode {
2138          volatile Node linkage;
2139 <        LinkedWeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm,
2139 >        LinkedWeakKeySelfValueNode(int locator, Object key,
2140 >                                   CustomConcurrentHashMap cchm,
2141                                     Node linkage) {
2142              super(locator, key, cchm);
2143              this.linkage = linkage;
# Line 2162 | Line 2166 | public class CustomConcurrentHashMap<K,
2166      static abstract class WeakKeyStrongValueNode
2167          extends WeakKeyNode {
2168          volatile Object value;
2169 <        WeakKeyStrongValueNode(int locator, Object key, Object value, CustomConcurrentHashMap cchm) {
2169 >        WeakKeyStrongValueNode(int locator, Object key, Object value,
2170 >                               CustomConcurrentHashMap cchm) {
2171              super(locator, key, cchm);
2172              this.value = value;
2173          }
# Line 2173 | Line 2178 | public class CustomConcurrentHashMap<K,
2178      static final class TerminalWeakKeyStrongValueNode
2179          extends WeakKeyStrongValueNode {
2180          TerminalWeakKeyStrongValueNode(int locator,
2181 <                                       Object key, Object value, CustomConcurrentHashMap cchm) {
2181 >                                       Object key, Object value,
2182 >                                       CustomConcurrentHashMap cchm) {
2183              super(locator, key, value, cchm);
2184          }
2185          public final Node getLinkage() { return null; }
# Line 2184 | Line 2190 | public class CustomConcurrentHashMap<K,
2190          extends WeakKeyStrongValueNode {
2191          volatile Node linkage;
2192          LinkedWeakKeyStrongValueNode(int locator,
2193 <                                     Object key, Object value, CustomConcurrentHashMap cchm,
2193 >                                     Object key, Object value,
2194 >                                     CustomConcurrentHashMap cchm,
2195                                       Node linkage) {
2196              super(locator, key, value, cchm);
2197              this.linkage = linkage;
# Line 2275 | Line 2282 | public class CustomConcurrentHashMap<K,
2282          }
2283          public final Object getValue() {
2284              EmbeddedWeakReference vr = valueRef;
2285 <            return vr == null? null : vr.get();
2285 >            return (vr == null) ? null : vr.get();
2286          }
2287          public final void setValue(Object value) {
2288              if (value == null)
# Line 2338 | Line 2345 | public class CustomConcurrentHashMap<K,
2345          }
2346          public final Object getValue() {
2347              EmbeddedSoftReference vr = valueRef;
2348 <            return vr == null? null : vr.get();
2348 >            return (vr == null) ? null : vr.get();
2349          }
2350          public final void setValue(Object value) {
2351              if (value == null)
# Line 2396 | Line 2403 | public class CustomConcurrentHashMap<K,
2403          final int locator;
2404          final CustomConcurrentHashMap cchm;
2405          SoftKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2406 <            super(key);
2406 >            super(key, getReclamationQueue());
2407              this.locator = locator;
2408              this.cchm = cchm;
2409          }
# Line 2409 | Line 2416 | public class CustomConcurrentHashMap<K,
2416  
2417      static abstract class SoftKeySelfValueNode
2418          extends SoftKeyNode {
2419 <        SoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2419 >        SoftKeySelfValueNode(int locator, Object key,
2420 >                             CustomConcurrentHashMap cchm) {
2421              super(locator, key, cchm);
2422          }
2423          public final Object getValue() { return get(); }
# Line 2418 | Line 2426 | public class CustomConcurrentHashMap<K,
2426  
2427      static final class TerminalSoftKeySelfValueNode
2428          extends SoftKeySelfValueNode {
2429 <        TerminalSoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2429 >        TerminalSoftKeySelfValueNode(int locator, Object key,
2430 >                                     CustomConcurrentHashMap cchm) {
2431              super(locator, key, cchm);
2432          }
2433          public final Node getLinkage() { return null; }
# Line 2428 | Line 2437 | public class CustomConcurrentHashMap<K,
2437      static final class LinkedSoftKeySelfValueNode
2438          extends SoftKeySelfValueNode {
2439          volatile Node linkage;
2440 <        LinkedSoftKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm,
2440 >        LinkedSoftKeySelfValueNode(int locator, Object key,
2441 >                                   CustomConcurrentHashMap cchm,
2442                                     Node linkage) {
2443              super(locator, key, cchm);
2444              this.linkage = linkage;
# Line 2457 | Line 2467 | public class CustomConcurrentHashMap<K,
2467      static abstract class SoftKeyStrongValueNode
2468          extends SoftKeyNode {
2469          volatile Object value;
2470 <        SoftKeyStrongValueNode(int locator, Object key, Object value, CustomConcurrentHashMap cchm) {
2470 >        SoftKeyStrongValueNode(int locator, Object key, Object value,
2471 >                               CustomConcurrentHashMap cchm) {
2472              super(locator, key, cchm);
2473              this.value = value;
2474          }
# Line 2468 | Line 2479 | public class CustomConcurrentHashMap<K,
2479      static final class TerminalSoftKeyStrongValueNode
2480          extends SoftKeyStrongValueNode {
2481          TerminalSoftKeyStrongValueNode(int locator,
2482 <                                       Object key, Object value, CustomConcurrentHashMap cchm) {
2482 >                                       Object key, Object value,
2483 >                                       CustomConcurrentHashMap cchm) {
2484              super(locator, key, value, cchm);
2485          }
2486          public final Node getLinkage() { return null; }
# Line 2479 | Line 2491 | public class CustomConcurrentHashMap<K,
2491          extends SoftKeyStrongValueNode {
2492          volatile Node linkage;
2493          LinkedSoftKeyStrongValueNode(int locator,
2494 <                                     Object key, Object value, CustomConcurrentHashMap cchm,
2494 >                                     Object key, Object value,
2495 >                                     CustomConcurrentHashMap cchm,
2496                                       Node linkage) {
2497              super(locator, key, value, cchm);
2498              this.linkage = linkage;
# Line 2570 | Line 2583 | public class CustomConcurrentHashMap<K,
2583          }
2584          public final Object getValue() {
2585              EmbeddedWeakReference vr = valueRef;
2586 <            return vr == null? null : vr.get();
2586 >            return (vr == null) ? null : vr.get();
2587          }
2588          public final void setValue(Object value) {
2589              if (value == null)
# Line 2633 | Line 2646 | public class CustomConcurrentHashMap<K,
2646          }
2647          public final Object getValue() {
2648              EmbeddedSoftReference vr = valueRef;
2649 <            return vr == null? null : vr.get();
2649 >            return (vr == null) ? null : vr.get();
2650          }
2651          public final void setValue(Object value) {
2652              if (value == null)
# Line 2861 | Line 2874 | public class CustomConcurrentHashMap<K,
2874          }
2875          public final Object getValue() {
2876              EmbeddedWeakReference vr = valueRef;
2877 <            return vr == null? null : vr.get();
2877 >            return (vr == null) ? null : vr.get();
2878          }
2879          public final void setValue(Object value) {
2880              if (value == null)
# Line 2918 | Line 2931 | public class CustomConcurrentHashMap<K,
2931          volatile EmbeddedSoftReference valueRef;
2932          final CustomConcurrentHashMap cchm;
2933          IntKeySoftValueNode(int locator, Object key, Object value,
2934 <                               CustomConcurrentHashMap cchm) {
2934 >                            CustomConcurrentHashMap cchm) {
2935              super(locator, key);
2936              this.cchm = cchm;
2937              if (value != null)
# Line 2929 | Line 2942 | public class CustomConcurrentHashMap<K,
2942          }
2943          public final Object getValue() {
2944              EmbeddedSoftReference vr = valueRef;
2945 <            return vr == null? null : vr.get();
2945 >            return (vr == null) ? null : vr.get();
2946          }
2947          public final void setValue(Object value) {
2948              if (value == null)
# Line 2984 | Line 2997 | public class CustomConcurrentHashMap<K,
2997  
2998      // Temporary Unsafe mechanics for preliminary release
2999  
3000 <    static final Unsafe _unsafe;
3000 >    static final Unsafe UNSAFE;
3001      static final long tableBase;
3002      static final int tableShift;
3003      static final long segmentsBase;
3004      static final int segmentsShift;
3005  
2993    private static Unsafe getUnsafe() throws Throwable {
2994        try {
2995            return Unsafe.getUnsafe();
2996        } catch (SecurityException se) {
2997            try {
2998                return java.security.AccessController.doPrivileged
2999                    (new java.security.PrivilegedExceptionAction<Unsafe>() {
3000                        public Unsafe run() throws Exception {
3001                            return getUnsafePrivileged();
3002                        }});
3003            } catch (java.security.PrivilegedActionException e) {
3004                throw e.getCause();
3005            }
3006        }
3007    }
3008
3009    private static Unsafe getUnsafePrivileged()
3010        throws NoSuchFieldException, IllegalAccessException {
3011        Field f = Unsafe.class.getDeclaredField("theUnsafe");
3012        f.setAccessible(true);
3013        return (Unsafe) f.get(null);
3014    }
3015
3006      static {
3007          try {
3008 <            _unsafe = getUnsafe();
3009 <            tableBase = _unsafe.arrayBaseOffset(Node[].class);
3010 <            int s = _unsafe.arrayIndexScale(Node[].class);
3008 >            UNSAFE = getUnsafe();
3009 >            tableBase = UNSAFE.arrayBaseOffset(Node[].class);
3010 >            int s = UNSAFE.arrayIndexScale(Node[].class);
3011              if ((s & (s-1)) != 0)
3012                  throw new Error("data type scale not a power of two");
3013              tableShift = 31 - Integer.numberOfLeadingZeros(s);
3014 <            segmentsBase = _unsafe.arrayBaseOffset(Segment[].class);
3015 <            s = _unsafe.arrayIndexScale(Segment[].class);
3014 >            segmentsBase = UNSAFE.arrayBaseOffset(Segment[].class);
3015 >            s = UNSAFE.arrayIndexScale(Segment[].class);
3016              if ((s & (s-1)) != 0)
3017                  throw new Error("data type scale not a power of two");
3018              segmentsShift = 31 - Integer.numberOfLeadingZeros(s);
# Line 3032 | Line 3022 | public class CustomConcurrentHashMap<K,
3022      }
3023  
3024      // Fenced store into segment table array. Unneeded when we have Fences
3025 <    static final  void storeNode(Node[] table,
3026 <                                 int i, Node r) {
3025 >    static final void storeNode(Node[] table,
3026 >                                int i, Node r) {
3027          long nodeOffset = ((long) i << tableShift) + tableBase;
3028 <        _unsafe.putOrderedObject(table, nodeOffset, r);
3028 >        UNSAFE.putOrderedObject(table, nodeOffset, r);
3029      }
3030  
3031 <    static final  void storeSegment(Segment[] segs,
3032 <                                    int i, Segment s) {
3031 >    static final void storeSegment(Segment[] segs,
3032 >                                   int i, Segment s) {
3033          long segmentOffset = ((long) i << segmentsShift) + segmentsBase;
3034 <        _unsafe.putOrderedObject(segs, segmentOffset, s);
3034 >        UNSAFE.putOrderedObject(segs, segmentOffset, s);
3035      }
3036  
3037 <
3037 >    /**
3038 >     * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
3039 >     * Replace with a simple call to Unsafe.getUnsafe when integrating
3040 >     * into a jdk.
3041 >     *
3042 >     * @return a sun.misc.Unsafe
3043 >     */
3044 >    private static sun.misc.Unsafe getUnsafe() {
3045 >        try {
3046 >            return sun.misc.Unsafe.getUnsafe();
3047 >        } catch (SecurityException tryReflectionInstead) {}
3048 >        try {
3049 >            return java.security.AccessController.doPrivileged
3050 >            (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
3051 >                public sun.misc.Unsafe run() throws Exception {
3052 >                    Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
3053 >                    for (java.lang.reflect.Field f : k.getDeclaredFields()) {
3054 >                        f.setAccessible(true);
3055 >                        Object x = f.get(null);
3056 >                        if (k.isInstance(x))
3057 >                            return k.cast(x);
3058 >                    }
3059 >                    throw new NoSuchFieldError("the Unsafe");
3060 >                }});
3061 >        } catch (java.security.PrivilegedActionException e) {
3062 >            throw new RuntimeException("Could not initialize intrinsics",
3063 >                                       e.getCause());
3064 >        }
3065 >    }
3066   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines