/* * Copyright 2015 Terracotta, Inc., a Software AG company. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terracotta.offheapstore.disk.storage; import org.terracotta.offheapstore.disk.storage.AATreeFileAllocator; import java.util.HashMap; import java.util.Map; import java.util.Random; import static org.hamcrest.core.Is.is; import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertThat; /** * * @author cdennis */ public class AATreeFileAllocatorTest { private static final int MAX_SIZE = 1024; private static final int CYCLES = 100; private static final int ENTRIES = 10000; @Test public void testAllocatorCorrectness() { AATreeFileAllocator allocator = new AATreeFileAllocator(Integer.MAX_VALUE); Map<Integer, AllocatedRegion> allocated = new HashMap<Integer, AllocatedRegion>(); long occupied = 0; Random rndm = new Random(); for (int i = 0; i < ENTRIES; i++) { allocator.allocate(Integer.SIZE + 1); occupied += Integer.SIZE << 1; long size = 1 + rndm.nextInt(MAX_SIZE - 1);// + Integer.SIZE + 1; long address = allocator.allocate(size); occupied += Long.bitCount(size) == 1 ? size : Long.highestOneBit(size) << 1; assertThat(allocator.occupied(), is(occupied)); allocated.put(i, new AllocatedRegion(address, size)); } for (int i = 0; i < ENTRIES; i++) { int key = rndm.nextInt(ENTRIES); AllocatedRegion existing = allocated.get(key); long size = 1 + rndm.nextInt(MAX_SIZE - 1);// + Integer.SIZE + 1; long address = allocator.allocate(size); allocated.put(key, new AllocatedRegion(address, size)); allocator.free(existing.address(), existing.size()); } } @Test @Ignore("performance test") public void testFragmentation() { AATreeFileAllocator allocator = new AATreeFileAllocator(Integer.MAX_VALUE); Map<Integer, AllocatedRegion> allocated = new HashMap<Integer, AllocatedRegion>(); long total = 0; Random rndm = new Random(); for (int i = 0; i < ENTRIES; i++) { allocator.allocate(Integer.SIZE + 1); long size = 1 + rndm.nextInt(MAX_SIZE - 1);// + Integer.SIZE + 1; long address = allocator.allocate(size); allocated.put(i, new AllocatedRegion(address, size)); } for (int c = 0; c < CYCLES; c++) { for (int i = 0; i < ENTRIES; i++) { int key = rndm.nextInt(ENTRIES); AllocatedRegion existing = allocated.get(key); long size = 1 + rndm.nextInt(MAX_SIZE - 1);// + Integer.SIZE + 1; long address = allocator.allocate(size); allocated.put(key, new AllocatedRegion(address, size)); allocator.free(existing.address(), existing.size()); } // long count = allocator.getRegionCount(); // total += count; System.err.println(c); } System.err.println("Running Average " + (((double) total) / CYCLES)); } static class AllocatedRegion { final long address; final long size; AllocatedRegion(long address, long size) { this.address = address; this.size = size; } long address() { return address; } long size() { return size; } } }