FreeListManager { OffHeapStoredObject allocateFromFragment(final int fragIdx, final int chunkSize) { if (fragIdx >= this.fragmentList.size()) return null; final Fragment fragment; try { fragment = this.fragmentList.get(fragIdx); } catch (IndexOutOfBoundsException ignore) { return null; } boolean retryFragment; do { retryFragment = false; int oldOffset = fragment.getFreeIndex(); int fragmentSize = fragment.getSize(); int fragmentFreeSize = fragmentSize - oldOffset; if (fragmentFreeSize >= chunkSize) { int newOffset = oldOffset + chunkSize; int extraSize = fragmentSize - newOffset; if (extraSize < OffHeapStoredObject.MIN_CHUNK_SIZE) { newOffset += extraSize; } else { extraSize = 0; } if (fragment.allocate(oldOffset, newOffset)) { this.lastFragmentAllocation.set(fragIdx); OffHeapStoredObject result = new OffHeapStoredObject(fragment.getAddress() + oldOffset, chunkSize + extraSize); checkDataIntegrity(result); return result; } else { OffHeapStoredObject result = basicAllocate(chunkSize, false); if (result != null) { return result; } retryFragment = true; } } } while (retryFragment); return null; } FreeListManager(MemoryAllocatorImpl ma, final Slab[] slabs); long getUsedMemory(); long getFreeMemory(); @SuppressWarnings("synthetic-access") OffHeapStoredObject allocate(int size); @SuppressWarnings("synthetic-access") void free(long addr); static final int TINY_MULTIPLE; static final int TINY_FREE_LIST_COUNT; static final int HUGE_MULTIPLE; static final int MAX_TINY; }
@Test public void allocateFromFragmentWithBadIndexesReturnsNull() { Slab chunk = new SlabImpl(96); this.freeListManager = createFreeListManager(ma, new Slab[] {chunk}); assertThat(this.freeListManager.allocateFromFragment(-1, 32)).isNull(); assertThat(this.freeListManager.allocateFromFragment(1, 32)).isNull(); }