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.14 by jsr166, Fri Oct 22 05:18:30 2010 UTC

# 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 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 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      }
# 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 696 | Line 700 | public class CustomConcurrentHashMap<K,
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 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 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 1554 | Line 1558 | public class CustomConcurrentHashMap<K,
1558       * for each key-value mapping, followed by a null pair.
1559       * The key-value mappings are emitted in no particular order.
1560       */
1561 <    private void writeObject(java.io.ObjectOutputStream s) throws IOException  {
1561 >    private void writeObject(java.io.ObjectOutputStream s) throws IOException {
1562          s.defaultWriteObject();
1563          for (Map.Entry<K,V> e : entrySet()) {
1564              s.writeObject(e.getKey());
# Line 1569 | Line 1573 | public class CustomConcurrentHashMap<K,
1573       * @param s the stream
1574       */
1575      private void readObject(java.io.ObjectInputStream s)
1576 <        throws IOException, ClassNotFoundException  {
1576 >        throws IOException, ClassNotFoundException {
1577          s.defaultReadObject();
1578          this.segments = (Segment[])(new Segment[NSEGMENTS]);
1579          for (;;) {
# Line 1971 | Line 1975 | public class CustomConcurrentHashMap<K,
1975          }
1976          public final Object getValue() {
1977              EmbeddedWeakReference vr = valueRef;
1978 <            return vr == null? null : vr.get();
1978 >            return (vr == null) ? null : vr.get();
1979          }
1980          public final void setValue(Object value) {
1981              if (value == null)
# Line 2039 | Line 2043 | public class CustomConcurrentHashMap<K,
2043          }
2044          public final Object getValue() {
2045              EmbeddedSoftReference vr = valueRef;
2046 <            return vr == null? null : vr.get();
2046 >            return (vr == null) ? null : vr.get();
2047          }
2048          public final void setValue(Object value) {
2049              if (value == null)
# Line 2097 | Line 2101 | public class CustomConcurrentHashMap<K,
2101          final int locator;
2102          final CustomConcurrentHashMap cchm;
2103          WeakKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2104 <            super(key);
2104 >            super(key, getReclamationQueue());
2105              this.locator = locator;
2106              this.cchm = cchm;
2107          }
# Line 2119 | Line 2123 | public class CustomConcurrentHashMap<K,
2123  
2124      static final class TerminalWeakKeySelfValueNode
2125          extends WeakKeySelfValueNode {
2126 <        TerminalWeakKeySelfValueNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2126 >        TerminalWeakKeySelfValueNode(int locator, Object key,
2127 >                                     CustomConcurrentHashMap cchm) {
2128              super(locator, key, cchm);
2129          }
2130          public final Node getLinkage() { return null; }
# Line 2271 | Line 2276 | public class CustomConcurrentHashMap<K,
2276          }
2277          public final Object getValue() {
2278              EmbeddedWeakReference vr = valueRef;
2279 <            return vr == null? null : vr.get();
2279 >            return (vr == null) ? null : vr.get();
2280          }
2281          public final void setValue(Object value) {
2282              if (value == null)
# Line 2334 | Line 2339 | public class CustomConcurrentHashMap<K,
2339          }
2340          public final Object getValue() {
2341              EmbeddedSoftReference vr = valueRef;
2342 <            return vr == null? null : vr.get();
2342 >            return (vr == null) ? null : vr.get();
2343          }
2344          public final void setValue(Object value) {
2345              if (value == null)
# Line 2392 | Line 2397 | public class CustomConcurrentHashMap<K,
2397          final int locator;
2398          final CustomConcurrentHashMap cchm;
2399          SoftKeyNode(int locator, Object key, CustomConcurrentHashMap cchm) {
2400 <            super(key);
2400 >            super(key, getReclamationQueue());
2401              this.locator = locator;
2402              this.cchm = cchm;
2403          }
# Line 2566 | Line 2571 | public class CustomConcurrentHashMap<K,
2571          }
2572          public final Object getValue() {
2573              EmbeddedWeakReference vr = valueRef;
2574 <            return vr == null? null : vr.get();
2574 >            return (vr == null) ? null : vr.get();
2575          }
2576          public final void setValue(Object value) {
2577              if (value == null)
# Line 2629 | Line 2634 | public class CustomConcurrentHashMap<K,
2634          }
2635          public final Object getValue() {
2636              EmbeddedSoftReference vr = valueRef;
2637 <            return vr == null? null : vr.get();
2637 >            return (vr == null) ? null : vr.get();
2638          }
2639          public final void setValue(Object value) {
2640              if (value == null)
# Line 2857 | Line 2862 | public class CustomConcurrentHashMap<K,
2862          }
2863          public final Object getValue() {
2864              EmbeddedWeakReference vr = valueRef;
2865 <            return vr == null? null : vr.get();
2865 >            return (vr == null) ? null : vr.get();
2866          }
2867          public final void setValue(Object value) {
2868              if (value == null)
# Line 2914 | Line 2919 | public class CustomConcurrentHashMap<K,
2919          volatile EmbeddedSoftReference valueRef;
2920          final CustomConcurrentHashMap cchm;
2921          IntKeySoftValueNode(int locator, Object key, Object value,
2922 <                               CustomConcurrentHashMap cchm) {
2922 >                            CustomConcurrentHashMap cchm) {
2923              super(locator, key);
2924              this.cchm = cchm;
2925              if (value != null)
# Line 2925 | Line 2930 | public class CustomConcurrentHashMap<K,
2930          }
2931          public final Object getValue() {
2932              EmbeddedSoftReference vr = valueRef;
2933 <            return vr == null? null : vr.get();
2933 >            return (vr == null) ? null : vr.get();
2934          }
2935          public final void setValue(Object value) {
2936              if (value == null)
# Line 2980 | Line 2985 | public class CustomConcurrentHashMap<K,
2985  
2986      // Temporary Unsafe mechanics for preliminary release
2987  
2988 <    static final Unsafe _unsafe;
2988 >    static final Unsafe UNSAFE;
2989      static final long tableBase;
2990      static final int tableShift;
2991      static final long segmentsBase;
# Line 3011 | Line 3016 | public class CustomConcurrentHashMap<K,
3016  
3017      static {
3018          try {
3019 <            _unsafe = getUnsafe();
3020 <            tableBase = _unsafe.arrayBaseOffset(Node[].class);
3021 <            int s = _unsafe.arrayIndexScale(Node[].class);
3019 >            UNSAFE = getUnsafe();
3020 >            tableBase = UNSAFE.arrayBaseOffset(Node[].class);
3021 >            int s = UNSAFE.arrayIndexScale(Node[].class);
3022              if ((s & (s-1)) != 0)
3023                  throw new Error("data type scale not a power of two");
3024              tableShift = 31 - Integer.numberOfLeadingZeros(s);
3025 <            segmentsBase = _unsafe.arrayBaseOffset(Segment[].class);
3026 <            s = _unsafe.arrayIndexScale(Segment[].class);
3025 >            segmentsBase = UNSAFE.arrayBaseOffset(Segment[].class);
3026 >            s = UNSAFE.arrayIndexScale(Segment[].class);
3027              if ((s & (s-1)) != 0)
3028                  throw new Error("data type scale not a power of two");
3029              segmentsShift = 31 - Integer.numberOfLeadingZeros(s);
# Line 3030 | Line 3035 | public class CustomConcurrentHashMap<K,
3035      // Fenced store into segment table array. Unneeded when we have Fences
3036      static final  void storeNode(Node[] table,
3037                                   int i, Node r) {
3038 <        _unsafe.putOrderedObject(table, (i << tableShift) + tableBase, r);
3038 >        long nodeOffset = ((long) i << tableShift) + tableBase;
3039 >        UNSAFE.putOrderedObject(table, nodeOffset, r);
3040      }
3041  
3042      static final  void storeSegment(Segment[] segs,
3043                                      int i, Segment s) {
3044 <        _unsafe.putOrderedObject(segs, (i << segmentsShift) + segmentsBase, s);
3044 >        long segmentOffset = ((long) i << segmentsShift) + segmentsBase;
3045 >        UNSAFE.putOrderedObject(segs, segmentOffset, s);
3046      }
3047  
3048  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines