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; |
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); |
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); |
537 |
|
while (capacity < sc) |
538 |
|
capacity <<= 1; |
539 |
|
if (capacity > MAX_SEGMENT_CAPACITY) |
540 |
< |
capacity = MAX_SEGMENT_CAPACITY; |
540 |
> |
capacity = MAX_SEGMENT_CAPACITY; |
541 |
|
this.initialSegmentCapacity = capacity; |
542 |
|
} |
543 |
|
this.segments = (Segment[])new Segment[NSEGMENTS]; |
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(); |
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 |
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(); |
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 |
|
/** |
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)) |
1158 |
|
* <pre> |
1159 |
|
* map.compute(word, new RemappingFunction<String,Integer>() { |
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 |
|
* |
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(); |
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()); |
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 (;;) { |
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); |
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) |
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) |
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 |
|
} |
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(); } |
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; } |
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; |
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 |
|
} |
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; } |
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; |
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) |
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) |
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 |
|
} |
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(); } |
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; } |
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; |
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 |
|
} |
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; } |
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; |
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) |
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) |
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) |
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) |
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) |
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; |
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); |
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 |
|
|