2141 |
|
} |
2142 |
|
|
2143 |
|
Node<K,V> find(int h, Object k) { |
2144 |
< |
Node<K,V> e; int n; |
2145 |
< |
Node<K,V>[] tab = nextTable; |
2146 |
< |
if (k != null && tab != null && (n = tab.length) > 0 && |
2147 |
< |
(e = tabAt(tab, (n - 1) & h)) != null) { |
2148 |
< |
do { |
2144 |
> |
// loop to avoid arbitrarily deep recursion on forwarding nodes |
2145 |
> |
outer: for (Node<K,V>[] tab = nextTable;;) { |
2146 |
> |
Node<K,V> e; int n; |
2147 |
> |
if (k == null || tab == null || (n = tab.length) == 0 || |
2148 |
> |
(e = tabAt(tab, (n - 1) & h)) == null) |
2149 |
> |
return null; |
2150 |
> |
for (;;) { |
2151 |
|
int eh; K ek; |
2152 |
|
if ((eh = e.hash) == h && |
2153 |
|
((ek = e.key) == k || (ek != null && k.equals(ek)))) |
2154 |
|
return e; |
2155 |
< |
if (eh < 0) |
2156 |
< |
return e.find(h, k); |
2157 |
< |
} while ((e = e.next) != null); |
2155 |
> |
if (eh < 0) { |
2156 |
> |
if (e instanceof ForwardingNode) { |
2157 |
> |
tab = ((ForwardingNode<K,V>)e).nextTable; |
2158 |
> |
continue outer; |
2159 |
> |
} |
2160 |
> |
else |
2161 |
> |
return e.find(h, k); |
2162 |
> |
} |
2163 |
> |
if ((e = e.next) == null) |
2164 |
> |
return null; |
2165 |
> |
} |
2166 |
|
} |
2157 |
– |
return null; |
2167 |
|
} |
2168 |
|
} |
2169 |
|
|
2337 |
|
int nextn = nextTab.length; |
2338 |
|
ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab); |
2339 |
|
boolean advance = true; |
2340 |
+ |
boolean finishing = false; // to ensure sweep before committing nextTab |
2341 |
|
for (int i = 0, bound = 0;;) { |
2342 |
|
int nextIndex, nextBound, fh; Node<K,V> f; |
2343 |
|
while (advance) { |
2344 |
< |
if (--i >= bound) |
2344 |
> |
if (--i >= bound || finishing) |
2345 |
|
advance = false; |
2346 |
|
else if ((nextIndex = transferIndex) <= transferOrigin) { |
2347 |
|
i = -1; |
2357 |
|
} |
2358 |
|
} |
2359 |
|
if (i < 0 || i >= n || i + n >= nextn) { |
2360 |
+ |
if (finishing) { |
2361 |
+ |
nextTable = null; |
2362 |
+ |
table = nextTab; |
2363 |
+ |
sizeCtl = (n << 1) - (n >>> 1); |
2364 |
+ |
return; |
2365 |
+ |
} |
2366 |
|
for (int sc;;) { |
2367 |
|
if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) { |
2368 |
< |
if (sc == -1) { |
2369 |
< |
nextTable = null; |
2370 |
< |
table = nextTab; |
2371 |
< |
sizeCtl = (n << 1) - (n >>> 1); |
2372 |
< |
} |
2357 |
< |
return; |
2368 |
> |
if (sc != -1) |
2369 |
> |
return; |
2370 |
> |
finishing = advance = true; |
2371 |
> |
i = n; // recheck before commit |
2372 |
> |
break; |
2373 |
|
} |
2374 |
|
} |
2375 |
|
} |