/** * Ensure this container can hold at least the * given number of elements without resizing its buffers. * * @param expectedElements The total number of elements, inclusive. */ @Override public void ensureCapacity(int expectedElements) { if (expectedElements > resizeAt || keys == null) { final int[] prevKeys = this.keys; allocateBuffers(minBufferSize(expectedElements, loadFactor)); if (prevKeys != null && !isEmpty()) { rehash(prevKeys); } } }
/** * This method is invoked when there is a new key to be inserted into * the buffer but there is not enough empty slots to do so. * * New buffers are allocated. If this succeeds, we know we can proceed * with rehashing so we assign the pending element to the previous buffer * (possibly violating the invariant of having at least one empty slot) * and rehash all keys, substituting new buffers at the end. */ protected void allocateThenInsertThenRehash(int slot, int pendingKey) { assert assigned == resizeAt && (( keys[slot]) == 0) && !((pendingKey) == 0); // Try to allocate new buffers first. If we OOM, we leave in a consistent state. final int[] prevKeys = this.keys; allocateBuffers(nextBufferSize(mask + 1, size(), loadFactor)); assert this.keys.length > prevKeys.length; // We have succeeded at allocating new data so insert the pending key/value at // the free slot in the old arrays before rehashing. prevKeys[slot] = pendingKey; // Rehash old keys, including the pending key. rehash(prevKeys); }
/** * Ensure this container can hold at least the * given number of elements without resizing its buffers. * * @param expectedElements The total number of elements, inclusive. */ @Override public void ensureCapacity(int expectedElements) { if (expectedElements > resizeAt || keys == null) { final int[] prevKeys = this.keys; allocateBuffers(minBufferSize(expectedElements, loadFactor)); if (prevKeys != null && !isEmpty()) { rehash(prevKeys); } } }
@Override protected void allocateBuffers(int arraySize) { long newMemSize = (arraySize + 1) * 4l; // array size + emtpyElementSlot long oldMemSize = keys == null ? 0 : keys.length * 4l; // Adjust the breaker with the new memory size breaker.addEstimateBytesAndMaybeBreak(newMemSize, "<terms_set>"); try { // Allocate the new buffer super.allocateBuffers(arraySize); // Adjust the breaker by removing old memory size breaker.addWithoutBreaking(-oldMemSize); } catch (BufferAllocationException e) { // If the allocation failed, remove breaker.addWithoutBreaking(-newMemSize); } }
/** * This method is invoked when there is a new key to be inserted into * the buffer but there is not enough empty slots to do so. * * New buffers are allocated. If this succeeds, we know we can proceed * with rehashing so we assign the pending element to the previous buffer * (possibly violating the invariant of having at least one empty slot) * and rehash all keys, substituting new buffers at the end. */ protected void allocateThenInsertThenRehash(int slot, int pendingKey) { assert assigned == resizeAt && (( keys[slot]) == 0) && !((pendingKey) == 0); // Try to allocate new buffers first. If we OOM, we leave in a consistent state. final int[] prevKeys = this.keys; allocateBuffers(nextBufferSize(mask + 1, size(), loadFactor)); assert this.keys.length > prevKeys.length; // We have succeeded at allocating new data so insert the pending key/value at // the free slot in the old arrays before rehashing. prevKeys[slot] = pendingKey; // Rehash old keys, including the pending key. rehash(prevKeys); }