79 |
|
* The default initial number of table slots for this table. |
80 |
|
* Used when not otherwise specified in constructor. |
81 |
|
*/ |
82 |
< |
private static int DEFAULT_INITIAL_CAPACITY = 16; |
82 |
> |
static int DEFAULT_INITIAL_CAPACITY = 16; |
83 |
|
|
84 |
|
/** |
85 |
|
* The maximum capacity, used if a higher value is implicitly |
98 |
|
/** |
99 |
|
* The default number of concurrency control segments. |
100 |
|
**/ |
101 |
< |
private static final int DEFAULT_SEGMENTS = 16; |
101 |
> |
static final int DEFAULT_SEGMENTS = 16; |
102 |
|
|
103 |
|
/** |
104 |
|
* The maximum number of segments to allow; used to bound |
105 |
|
* constructor arguments. |
106 |
|
*/ |
107 |
< |
private static final int MAX_SEGMENTS = 1 << 16; // slightly conservative |
107 |
> |
static final int MAX_SEGMENTS = 1 << 16; // slightly conservative |
108 |
|
|
109 |
|
/* ---------------- Fields -------------- */ |
110 |
|
|
112 |
|
* Mask value for indexing into segments. The upper bits of a |
113 |
|
* key's hash code are used to choose the segment. |
114 |
|
**/ |
115 |
< |
private final int segmentMask; |
115 |
> |
final int segmentMask; |
116 |
|
|
117 |
|
/** |
118 |
|
* Shift value for indexing within segments. |
119 |
|
**/ |
120 |
< |
private final int segmentShift; |
120 |
> |
final int segmentShift; |
121 |
|
|
122 |
|
/** |
123 |
|
* The segments, each of which is a specialized hash table |
124 |
|
*/ |
125 |
< |
private final Segment[] segments; |
125 |
> |
final Segment[] segments; |
126 |
|
|
127 |
< |
private transient Set<K> keySet; |
128 |
< |
private transient Set<Map.Entry<K,V>> entrySet; |
129 |
< |
private transient Collection<V> values; |
127 |
> |
transient Set<K> keySet; |
128 |
> |
transient Set<Map.Entry<K,V>> entrySet; |
129 |
> |
transient Collection<V> values; |
130 |
|
|
131 |
|
/* ---------------- Small Utilities -------------- */ |
132 |
|
|
136 |
|
* @param x the object serving as a key |
137 |
|
* @return the hash code |
138 |
|
*/ |
139 |
< |
private static int hash(Object x) { |
139 |
> |
static int hash(Object x) { |
140 |
|
int h = x.hashCode(); |
141 |
|
h += ~(h << 9); |
142 |
|
h ^= (h >>> 14); |
148 |
|
/** |
149 |
|
* Return the segment that should be used for key with given hash |
150 |
|
*/ |
151 |
< |
private Segment<K,V> segmentFor(int hash) { |
151 |
> |
final Segment<K,V> segmentFor(int hash) { |
152 |
|
return (Segment<K,V>) segments[(hash >>> segmentShift) & segmentMask]; |
153 |
|
} |
154 |
|
|
159 |
|
* subclasses from ReentrantLock opportunistically, just to |
160 |
|
* simplify some locking and avoid separate construction. |
161 |
|
**/ |
162 |
< |
private static final class Segment<K,V> extends ReentrantLock implements Serializable { |
162 |
> |
static final class Segment<K,V> extends ReentrantLock implements Serializable { |
163 |
|
/* |
164 |
|
* Segments maintain a table of entry lists that are ALWAYS |
165 |
|
* kept in a consistent state, so can be read without locking. |
218 |
|
* (The value of this field is always (int)(capacity * |
219 |
|
* loadFactor).) |
220 |
|
*/ |
221 |
< |
private transient int threshold; |
221 |
> |
transient int threshold; |
222 |
|
|
223 |
|
/** |
224 |
|
* The per-segment table |
231 |
|
* links to outer object. |
232 |
|
* @serial |
233 |
|
*/ |
234 |
< |
private final float loadFactor; |
234 |
> |
final float loadFactor; |
235 |
|
|
236 |
|
Segment(int initialCapacity, float lf) { |
237 |
|
loadFactor = lf; |
242 |
|
* Set table to new HashEntry array. |
243 |
|
* Call only while holding lock or in constructor. |
244 |
|
**/ |
245 |
< |
private void setTable(HashEntry[] newTable) { |
245 |
> |
void setTable(HashEntry[] newTable) { |
246 |
|
table = newTable; |
247 |
|
threshold = (int)(newTable.length * loadFactor); |
248 |
|
count = count; // write-volatile |
377 |
|
} |
378 |
|
} |
379 |
|
|
380 |
< |
private HashEntry[] rehash(HashEntry[] oldTable) { |
380 |
> |
HashEntry[] rehash(HashEntry[] oldTable) { |
381 |
|
int oldCapacity = oldTable.length; |
382 |
|
if (oldCapacity >= MAXIMUM_CAPACITY) |
383 |
|
return oldTable; |
497 |
|
* ConcurrentHashMap list entry. Note that this is never exported |
498 |
|
* out as a user-visible Map.Entry |
499 |
|
*/ |
500 |
< |
private static class HashEntry<K,V> { |
501 |
< |
private final K key; |
502 |
< |
private V value; |
503 |
< |
private final int hash; |
504 |
< |
private final HashEntry<K,V> next; |
500 |
> |
static final class HashEntry<K,V> { |
501 |
> |
final K key; |
502 |
> |
V value; |
503 |
> |
final int hash; |
504 |
> |
final HashEntry<K,V> next; |
505 |
|
|
506 |
|
HashEntry(int hash, K key, V value, HashEntry<K,V> next) { |
507 |
|
this.value = value; |
1023 |
|
|
1024 |
|
/* ---------------- Iterator Support -------------- */ |
1025 |
|
|
1026 |
< |
private abstract class HashIterator { |
1027 |
< |
private int nextSegmentIndex; |
1028 |
< |
private int nextTableIndex; |
1029 |
< |
private HashEntry[] currentTable; |
1030 |
< |
private HashEntry<K, V> nextEntry; |
1026 |
> |
abstract class HashIterator { |
1027 |
> |
int nextSegmentIndex; |
1028 |
> |
int nextTableIndex; |
1029 |
> |
HashEntry[] currentTable; |
1030 |
> |
HashEntry<K, V> nextEntry; |
1031 |
|
HashEntry<K, V> lastReturned; |
1032 |
|
|
1033 |
< |
private HashIterator() { |
1033 |
> |
HashIterator() { |
1034 |
|
nextSegmentIndex = segments.length - 1; |
1035 |
|
nextTableIndex = -1; |
1036 |
|
advance(); |
1038 |
|
|
1039 |
|
public boolean hasMoreElements() { return hasNext(); } |
1040 |
|
|
1041 |
< |
private void advance() { |
1041 |
> |
final void advance() { |
1042 |
|
if (nextEntry != null && (nextEntry = nextEntry.next) != null) |
1043 |
|
return; |
1044 |
|
|
1079 |
|
} |
1080 |
|
} |
1081 |
|
|
1082 |
< |
private class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> { |
1082 |
> |
final class KeyIterator extends HashIterator implements Iterator<K>, Enumeration<K> { |
1083 |
|
public K next() { return super.nextEntry().key; } |
1084 |
|
public K nextElement() { return super.nextEntry().key; } |
1085 |
|
} |
1086 |
|
|
1087 |
< |
private class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> { |
1087 |
> |
final class ValueIterator extends HashIterator implements Iterator<V>, Enumeration<V> { |
1088 |
|
public V next() { return super.nextEntry().value; } |
1089 |
|
public V nextElement() { return super.nextEntry().value; } |
1090 |
|
} |
1092 |
|
|
1093 |
|
|
1094 |
|
/** |
1095 |
< |
* Exported Entry objects must write-through changes in setValue, |
1096 |
< |
* even if the nodes have been cloned. So we cannot return |
1097 |
< |
* internal HashEntry objects. Instead, the iterator itself acts |
1098 |
< |
* as a forwarding pseudo-entry. |
1095 |
> |
* Entry iterator. Exported Entry objects must write-through |
1096 |
> |
* changes in setValue, even if the nodes have been cloned. So we |
1097 |
> |
* cannot return internal HashEntry objects. Instead, the iterator |
1098 |
> |
* itself acts as a forwarding pseudo-entry. |
1099 |
|
*/ |
1100 |
< |
private class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> { |
1100 |
> |
final class EntryIterator extends HashIterator implements Map.Entry<K,V>, Iterator<Entry<K,V>> { |
1101 |
|
public Map.Entry<K,V> next() { |
1102 |
|
nextEntry(); |
1103 |
|
return this; |
1143 |
|
return getKey() + "=" + getValue(); |
1144 |
|
} |
1145 |
|
|
1146 |
< |
private boolean eq(Object o1, Object o2) { |
1146 |
> |
boolean eq(Object o1, Object o2) { |
1147 |
|
return (o1 == null ? o2 == null : o1.equals(o2)); |
1148 |
|
} |
1149 |
|
|
1150 |
|
} |
1151 |
|
|
1152 |
< |
private class KeySet extends AbstractSet<K> { |
1152 |
> |
final class KeySet extends AbstractSet<K> { |
1153 |
|
public Iterator<K> iterator() { |
1154 |
|
return new KeyIterator(); |
1155 |
|
} |
1167 |
|
} |
1168 |
|
} |
1169 |
|
|
1170 |
< |
private class Values extends AbstractCollection<V> { |
1170 |
> |
final class Values extends AbstractCollection<V> { |
1171 |
|
public Iterator<V> iterator() { |
1172 |
|
return new ValueIterator(); |
1173 |
|
} |
1182 |
|
} |
1183 |
|
} |
1184 |
|
|
1185 |
< |
private class EntrySet extends AbstractSet<Map.Entry<K,V>> { |
1185 |
> |
final class EntrySet extends AbstractSet<Map.Entry<K,V>> { |
1186 |
|
public Iterator<Map.Entry<K,V>> iterator() { |
1187 |
|
return new EntryIterator(); |
1188 |
|
} |
1226 |
|
* This duplicates java.util.AbstractMap.SimpleEntry until this class |
1227 |
|
* is made accessible. |
1228 |
|
*/ |
1229 |
< |
static class SimpleEntry<K,V> implements Entry<K,V> { |
1229 |
> |
static final class SimpleEntry<K,V> implements Entry<K,V> { |
1230 |
|
K key; |
1231 |
|
V value; |
1232 |
|
|
1270 |
|
return key + "=" + value; |
1271 |
|
} |
1272 |
|
|
1273 |
< |
private static boolean eq(Object o1, Object o2) { |
1273 |
> |
static boolean eq(Object o1, Object o2) { |
1274 |
|
return (o1 == null ? o2 == null : o1.equals(o2)); |
1275 |
|
} |
1276 |
|
} |