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.5 by jsr166, Tue Oct 6 19:02:48 2009 UTC vs.
Revision 1.20 by jsr166, Mon Dec 5 04:08:47 2011 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 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 533 | 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      }
# Line 639 | 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 956 | 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 963 | Line 970 | public class CustomConcurrentHashMap<K,
970                              seg.decrementCount();
971                              p = n;
972                          }
966                        else {
967                            pred = p;
968                            p = n;
969                        }
973                      }
974                  }
975              } finally {
# Line 1007 | 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 1066 | 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 1155 | 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 1411 | 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 1547 | 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 1566 | 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 1972 | 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 2040 | 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 2098 | 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 2111 | 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 2120 | 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 2130 | 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 2159 | 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 2170 | 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 2181 | 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 2272 | 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 2335 | 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 2393 | 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 2406 | 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 2415 | 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 2425 | 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 2454 | 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 2465 | 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 2476 | 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 2567 | 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 2630 | 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 2858 | 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 2915 | 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 2926 | 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 2981 | 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;
# Line 3012 | Line 3028 | public class CustomConcurrentHashMap<K,
3028  
3029      static {
3030          try {
3031 <            _unsafe = getUnsafe();
3032 <            tableBase = _unsafe.arrayBaseOffset(Node[].class);
3033 <            int s = _unsafe.arrayIndexScale(Node[].class);
3031 >            UNSAFE = getUnsafe();
3032 >            tableBase = UNSAFE.arrayBaseOffset(Node[].class);
3033 >            int s = UNSAFE.arrayIndexScale(Node[].class);
3034              if ((s & (s-1)) != 0)
3035                  throw new Error("data type scale not a power of two");
3036              tableShift = 31 - Integer.numberOfLeadingZeros(s);
3037 <            segmentsBase = _unsafe.arrayBaseOffset(Segment[].class);
3038 <            s = _unsafe.arrayIndexScale(Segment[].class);
3037 >            segmentsBase = UNSAFE.arrayBaseOffset(Segment[].class);
3038 >            s = UNSAFE.arrayIndexScale(Segment[].class);
3039              if ((s & (s-1)) != 0)
3040                  throw new Error("data type scale not a power of two");
3041              segmentsShift = 31 - Integer.numberOfLeadingZeros(s);
# Line 3029 | Line 3045 | public class CustomConcurrentHashMap<K,
3045      }
3046  
3047      // Fenced store into segment table array. Unneeded when we have Fences
3048 <    static final  void storeNode(Node[] table,
3049 <                                 int i, Node r) {
3048 >    static final void storeNode(Node[] table,
3049 >                                int i, Node r) {
3050          long nodeOffset = ((long) i << tableShift) + tableBase;
3051 <        _unsafe.putOrderedObject(table, nodeOffset, r);
3051 >        UNSAFE.putOrderedObject(table, nodeOffset, r);
3052      }
3053  
3054 <    static final  void storeSegment(Segment[] segs,
3055 <                                    int i, Segment s) {
3054 >    static final void storeSegment(Segment[] segs,
3055 >                                   int i, Segment s) {
3056          long segmentOffset = ((long) i << segmentsShift) + segmentsBase;
3057 <        _unsafe.putOrderedObject(segs, segmentOffset, s);
3057 >        UNSAFE.putOrderedObject(segs, segmentOffset, s);
3058      }
3059  
3060  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines