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

Method expand

corpus/java/training/guava/cache/LocalCache.java:2938–3005  ·  view source on GitHub ↗

Expands the table if possible.

()

Source from the content-addressed store, hash-verified

2936 * Expands the table if possible.
2937 */
2938 @GuardedBy("this")
2939 void expand() {
2940 AtomicReferenceArray<ReferenceEntry<K, V>> oldTable = table;
2941 int oldCapacity = oldTable.length();
2942 if (oldCapacity >= MAXIMUM_CAPACITY) {
2943 return;
2944 }
2945
2946 /*
2947 * Reclassify nodes in each list to new Map. Because we are using power-of-two expansion, the
2948 * elements from each bin must either stay at same index, or move with a power of two offset.
2949 * We eliminate unnecessary node creation by catching cases where old nodes can be reused
2950 * because their next fields won't change. Statistically, at the default threshold, only about
2951 * one-sixth of them need cloning when a table doubles. The nodes they replace will be garbage
2952 * collectable as soon as they are no longer referenced by any reader thread that may be in
2953 * the midst of traversing table right now.
2954 */
2955
2956 int newCount = count;
2957 AtomicReferenceArray<ReferenceEntry<K, V>> newTable = newEntryArray(oldCapacity << 1);
2958 threshold = newTable.length() * 3 / 4;
2959 int newMask = newTable.length() - 1;
2960 for (int oldIndex = 0; oldIndex < oldCapacity; ++oldIndex) {
2961 // We need to guarantee that any existing reads of old Map can
2962 // proceed. So we cannot yet null out each bin.
2963 ReferenceEntry<K, V> head = oldTable.get(oldIndex);
2964
2965 if (head != null) {
2966 ReferenceEntry<K, V> next = head.getNext();
2967 int headIndex = head.getHash() & newMask;
2968
2969 // Single node on list
2970 if (next == null) {
2971 newTable.set(headIndex, head);
2972 } else {
2973 // Reuse the consecutive sequence of nodes with the same target
2974 // index from the end of the list. tail points to the first
2975 // entry in the reusable list.
2976 ReferenceEntry<K, V> tail = head;
2977 int tailIndex = headIndex;
2978 for (ReferenceEntry<K, V> e = next; e != null; e = e.getNext()) {
2979 int newIndex = e.getHash() & newMask;
2980 if (newIndex != tailIndex) {
2981 // The index changed. We'll need to copy the previous entry.
2982 tailIndex = newIndex;
2983 tail = e;
2984 }
2985 }
2986 newTable.set(tailIndex, tail);
2987
2988 // Clone nodes leading up to the tail.
2989 for (ReferenceEntry<K, V> e = head; e != tail; e = e.getNext()) {
2990 int newIndex = e.getHash() & newMask;
2991 ReferenceEntry<K, V> newNext = newTable.get(newIndex);
2992 ReferenceEntry<K, V> newFirst = copyEntry(e, newNext);
2993 if (newFirst != null) {
2994 newTable.set(newIndex, newFirst);
2995 } 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