840 |
|
// Try a few times to get accurate count. On failure due to |
841 |
|
// continuous async changes in table, resort to locking. |
842 |
|
final Segment<K,V>[] segments = this.segments; |
843 |
< |
int size; |
844 |
< |
boolean overflow; // true if size overflows 32 bits |
845 |
< |
long sum; // sum of modCounts |
846 |
< |
long last = 0L; // previous sum |
847 |
< |
int retries = -1; // first iteration isn't retry |
848 |
< |
try { |
849 |
< |
for (;;) { |
850 |
< |
if (retries++ == RETRIES_BEFORE_LOCK) { |
851 |
< |
for (int j = 0; j < segments.length; ++j) |
852 |
< |
ensureSegment(j).lock(); // force creation |
853 |
< |
} |
854 |
< |
sum = 0L; |
855 |
< |
size = 0; |
856 |
< |
overflow = false; |
857 |
< |
for (int j = 0; j < segments.length; ++j) { |
858 |
< |
Segment<K,V> seg = segmentAt(segments, j); |
859 |
< |
if (seg != null) { |
860 |
< |
sum += seg.modCount; |
861 |
< |
int c = seg.count; |
862 |
< |
if (c < 0 || (size += c) < 0) |
863 |
< |
overflow = true; |
864 |
< |
} |
843 |
> |
final int segmentCount = segments.length; |
844 |
> |
|
845 |
> |
long previousSum = 0L; |
846 |
> |
for (int retries = -1; retries < RETRIES_BEFORE_LOCK; retries++) { |
847 |
> |
long sum = 0L; // sum of modCounts |
848 |
> |
long size = 0L; |
849 |
> |
for (int i = 0; i < segmentCount; i++) { |
850 |
> |
Segment<K,V> segment = segmentAt(segments, i); |
851 |
> |
if (segment != null) { |
852 |
> |
sum += segment.modCount; |
853 |
> |
size += segment.count; |
854 |
|
} |
866 |
– |
if (sum == last) |
867 |
– |
break; |
868 |
– |
last = sum; |
869 |
– |
} |
870 |
– |
} finally { |
871 |
– |
if (retries > RETRIES_BEFORE_LOCK) { |
872 |
– |
for (int j = 0; j < segments.length; ++j) |
873 |
– |
segmentAt(segments, j).unlock(); |
855 |
|
} |
856 |
+ |
if (sum == previousSum) |
857 |
+ |
return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE; |
858 |
+ |
previousSum = sum; |
859 |
|
} |
860 |
< |
return overflow ? Integer.MAX_VALUE : size; |
860 |
> |
|
861 |
> |
long size = 0L; |
862 |
> |
for (int i = 0; i < segmentCount; i++) { |
863 |
> |
Segment<K,V> segment = ensureSegment(i); |
864 |
> |
segment.lock(); |
865 |
> |
size += segment.count; |
866 |
> |
} |
867 |
> |
for (int i = 0; i < segmentCount; i++) |
868 |
> |
segments[i].unlock(); |
869 |
> |
return ((size >>> 31) == 0) ? (int) size : Integer.MAX_VALUE; |
870 |
|
} |
871 |
|
|
872 |
|
/** |
942 |
|
if (value == null) |
943 |
|
throw new NullPointerException(); |
944 |
|
final Segment<K,V>[] segments = this.segments; |
945 |
< |
boolean found = false; |
946 |
< |
long last = 0L; // previous sum |
954 |
< |
int retries = -1; |
945 |
> |
long previousSum = 0L; |
946 |
> |
int lockCount = 0; |
947 |
|
try { |
948 |
< |
outer: for (;;) { |
949 |
< |
if (retries++ == RETRIES_BEFORE_LOCK) { |
950 |
< |
for (int j = 0; j < segments.length; ++j) |
951 |
< |
ensureSegment(j).lock(); // force creation |
952 |
< |
} |
953 |
< |
long sum = 0L; |
954 |
< |
for (int j = 0; j < segments.length; ++j) { |
955 |
< |
HashEntry<K,V>[] tab; |
956 |
< |
Segment<K,V> seg = segmentAt(segments, j); |
957 |
< |
if (seg != null && (tab = seg.table) != null) { |
948 |
> |
for (int retries = -1; ; retries++) { |
949 |
> |
long sum = 0L; // sum of modCounts |
950 |
> |
for (int j = 0; j < segments.length; j++) { |
951 |
> |
Segment<K,V> segment; |
952 |
> |
if (retries == RETRIES_BEFORE_LOCK) { |
953 |
> |
segment = ensureSegment(j); |
954 |
> |
segment.lock(); |
955 |
> |
lockCount++; |
956 |
> |
} else { |
957 |
> |
segment = segmentAt(segments, j); |
958 |
> |
if (segment == null) |
959 |
> |
continue; |
960 |
> |
} |
961 |
> |
HashEntry<K,V>[] tab = segment.table; |
962 |
> |
if (tab != null) { |
963 |
|
for (int i = 0 ; i < tab.length; i++) { |
964 |
|
HashEntry<K,V> e; |
965 |
|
for (e = entryAt(tab, i); e != null; e = e.next) { |
966 |
|
V v = e.value; |
967 |
< |
if (v != null && value.equals(v)) { |
968 |
< |
found = true; |
972 |
< |
break outer; |
973 |
< |
} |
967 |
> |
if (v != null && value.equals(v)) |
968 |
> |
return true; |
969 |
|
} |
970 |
|
} |
971 |
< |
sum += seg.modCount; |
971 |
> |
sum += segment.modCount; |
972 |
|
} |
973 |
|
} |
974 |
< |
if (retries > 0 && sum == last) |
975 |
< |
break; |
976 |
< |
last = sum; |
974 |
> |
if ((retries >= 0 && sum == previousSum) || lockCount > 0) |
975 |
> |
return false; |
976 |
> |
previousSum = sum; |
977 |
|
} |
978 |
|
} finally { |
979 |
< |
if (retries > RETRIES_BEFORE_LOCK) { |
980 |
< |
for (int j = 0; j < segments.length; ++j) |
986 |
< |
segmentAt(segments, j).unlock(); |
987 |
< |
} |
979 |
> |
for (int j = 0; j < lockCount; j++) |
980 |
> |
segments[j].unlock(); |
981 |
|
} |
989 |
– |
return found; |
982 |
|
} |
983 |
|
|
984 |
|
/** |