MCPcopy Create free account
hub / github.com/antlr/codebuff / expand

Method expand

output/java_guava/1.4.16/LocalCache.java:2991–3058  ·  view source on GitHub ↗

Expands the table if possible.

()

Source from the content-addressed store, hash-verified

2989 */
2990
2991 @GuardedBy("this")
2992 void expand() {
2993 AtomicReferenceArray<ReferenceEntry<K, V>> oldTable = table;
2994 int oldCapacity = oldTable.length();
2995 if (oldCapacity >= MAXIMUM_CAPACITY) {
2996 return;
2997 }
2998
2999 /*
3000 * Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the
3001 * elements from each bin must either stay at same index, or move with a power of two offset.
3002 * We eliminate unnecessary node creation by catching cases where old nodes can be reused
3003 * because their next fields won't change. Statistically, at the default threshold, only about
3004 * one-sixth of them need cloning when a table doubles. The nodes they replace will be garbage
3005 * collectable as soon as they are no longer referenced by any reader thread that may be in
3006 * the midst of traversing table right now.
3007 */
3008
3009 int newCount = count;
3010 AtomicReferenceArray<ReferenceEntry<K, V>> newTable = newEntryArray(oldCapacity << 1);
3011 threshold = newTable.length() * 3 / 4;
3012 int newMask = newTable.length() - 1;
3013 for (int oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) {
3014 // We need to guarantee that any existing reads of old Map can
3015 // proceed. So we cannot yet null out each bin.
3016 ReferenceEntry<K, V> head = oldTable.get(oldIndex);
3017 if (head != null) {
3018 ReferenceEntry<K, V> next = head.getNext();
3019 int headIndex = head.getHash() & newMask;
3020
3021 // Single node on list
3022 if (next == null) {
3023 newTable.set(headIndex, head);
3024 }
3025 else {
3026 // Reuse the consecutive sequence of nodes with the same target
3027 // index from the end of the list. tail points to the first
3028 // entry in the reusable list.
3029 ReferenceEntry<K, V> tail = head;
3030 int tailIndex = headIndex;
3031 for (ReferenceEntry<K, V> e = next; e != null; e = e.getNext()) {
3032 int newIndex = e.getHash() & newMask;
3033 if (newIndex != tailIndex) {
3034 // The index changed. We'll need to copy the previous entry.
3035 tailIndex = newIndex;
3036 tail = e;
3037 }
3038 }
3039 newTable.set(tailIndex, tail);
3040
3041 // Clone nodes leading up to the tail.
3042 for (ReferenceEntry<K, V> e = head; e != tail; e = e.getNext()) {
3043 int newIndex = e.getHash() & newMask;
3044 ReferenceEntry<K, V> newNext = newTable.get(newIndex);
3045 ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
3046 if (newFirst != null) {
3047 newTable.set(newIndex, newFirst);
3048 } else {

Callers 2

putMethod · 0.95
storeLoadedValueMethod · 0.95

Calls 8

newEntryArrayMethod · 0.95
copyEntryMethod · 0.95
removeCollectedEntryMethod · 0.95
getMethod · 0.65
getNextMethod · 0.65
getHashMethod · 0.65
setMethod · 0.65
lengthMethod · 0.45

Tested by

no test coverage detected