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.3 by jsr166, Wed Jul 22 17:50:01 2009 UTC vs.
Revision 1.25 by jsr166, Wed Jan 9 02:51:36 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 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;
59 > *             return (x instanceof Person) ? ((Person)x).name.hashCode() : 0;
60   *          }
61   *        },
62   *      STRONG, EQUALS, 0);
# Line 81 | Line 81 | import sun.misc.Unsafe;
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
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
87   * return from the method.
# 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 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,
# 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 532 | Line 533 | public class CustomConcurrentHashMap<K,
533              int sc = (int)((1L + (4L * es) / 3) >>> SEGMENT_BITS);
534              if (sc < MIN_SEGMENT_CAPACITY)
535                  sc = MIN_SEGMENT_CAPACITY;
536 <            else if (sc > MAX_SEGMENT_CAPACITY)
537 <                sc = MAX_SEGMENT_CAPACITY;
538 <            this.initialSegmentCapacity = sc;
536 >            int capacity = MIN_SEGMENT_CAPACITY; // ensure power of two
537 >            while (capacity < sc)
538 >                capacity <<= 1;
539 >            if (capacity > MAX_SEGMENT_CAPACITY)
540 >                capacity = MAX_SEGMENT_CAPACITY;
541 >            this.initialSegmentCapacity = capacity;
542          }
543          this.segments = (Segment[])new Segment[NSEGMENTS];
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 569 | 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 587 | 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 605 | 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 619 | 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 629 | Line 633 | public class CustomConcurrentHashMap<K,
633  
634      /**
635       * Returns the segment for possibly inserting into the table
636 <     * associated with given hash, constructing it if necesary.
636 >     * associated with given hash, constructing it if necessary.
637       * @param hash the hash code for the key
638       * @return the segment
639       */
# Line 638 | 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 652 | 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 693 | 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 kew or <tt>null</tt> if
703 >     * @return the value associated with the key or <tt>null</tt> if
704       * there is no mapping.
705       * @throws NullPointerException if the specified key is null
706       */
# Line 712 | Line 716 | public class CustomConcurrentHashMap<K,
716      }
717  
718      /**
719 <     * Share dimplementation for put, putIfAbsent
719 >     * Shared implementation for put, putIfAbsent
720       */
721      final V doPut(K key, V value, boolean onlyIfNull) {
722          if (key == null || value == null)
# Line 938 | 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 955 | Line 959 | public class CustomConcurrentHashMap<K,
959                      while (p != null) {
960                          Node n = p.getLinkage();
961                          if (p.get() != null && p.getValue() != null) {
962 +                            pred = p;
963 +                            p = n;
964 +                        }
965 +                        else {
966                              if (pred == null)
967                                  tab[i] = n;
968                              else
# Line 962 | Line 970 | public class CustomConcurrentHashMap<K,
970                              seg.decrementCount();
971                              p = n;
972                          }
965                        else {
966                            pred = p;
967                            p = n;
968                        }
973                      }
974                  }
975              } finally {
# Line 1006 | 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      /**
# Line 1065 | 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 1078 | Line 1082 | public class CustomConcurrentHashMap<K,
1082       * </pre>
1083       *
1084       * except that the action is performed atomically.  Some
1085 <     * attemmpted operations on this map by other threads may be
1085 >     * attempted operations on this map by other threads may be
1086       * blocked while computation is in progress. Because this function
1087       * is invoked within atomicity control, the computation should be
1088       * short and simple. The most common usage is to construct a new
# Line 1145 | Line 1149 | public class CustomConcurrentHashMap<K,
1149       *     return remove(key);
1150       * </pre>
1151       *
1152 <     * except that the action is performed atomically. Some attemmpted
1152 >     * except that the action is performed atomically. Some attempted
1153       * operations on this map by other threads may be blocked while
1154       * computation is in progress.
1155       *
# Line 1154 | 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       *
# Line 1410 | 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 1546 | 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 1565 | 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 1595 | 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 1616 | 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 1971 | 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 2039 | 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 2097 | 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 2110 | 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 2119 | 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 2129 | 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 2158 | 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 2169 | 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 2180 | 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 2271 | 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 2334 | 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 2392 | 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 2405 | 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 2414 | 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 2424 | 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 2453 | 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 2464 | 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 2475 | 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 2566 | 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 2629 | 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 2857 | 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 2914 | 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 2925 | 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 2980 | 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  
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
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 3028 | 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) {
3027 <        _unsafe.putOrderedObject(table, (i << tableShift) + tableBase, 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);
3029      }
3030  
3031 <    static final  void storeSegment(Segment[] segs,
3032 <                                    int i, Segment s) {
3033 <        _unsafe.putOrderedObject(segs, (i << segmentsShift) + segmentsBase, 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);
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