package com.ctriposs.bigmap;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import org.junit.After;
import org.junit.Test;
import com.ctriposs.bigmap.utils.FileUtil;
public class MapEntryFactoryTest {
private IMapEntryFactory mapEntryPool;
private String testDir = TestUtil.TEST_BASE_DIR + "bigmap/unit/map_entry_pool_test";
@Test
public void TestAcquireAndRelease() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "acquireAndReleaseTest");
// acquire new
MapEntry me = mapEntryPool.acquire(1024);
assertTrue(me.getIndex() == 0L); // new
me.putValueLength(1);
assertTrue(me.isReleased() == false);
assertTrue(me.isInUse() == true);
assertTrue(me.isAllocated() == true);
assertTrue(me.getSlotSize() == 1024);
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == 1);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
// acquire new
MapEntry me2 = mapEntryPool.acquire(4096);
assertTrue(me2.getIndex() == 1L); // new
assertTrue(me2.isReleased() == false);
assertTrue(me2.isInUse() == true);
assertTrue(me2.isAllocated() == true);
assertTrue(me2.getSlotSize() == 4096);
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == 2);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 5120);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
mapEntryPool.release(me2);
assertTrue(me2.isReleased() == true);
assertTrue(me2.isInUse() == false);
assertTrue(mapEntryPool.getFreeEntryCount() == 1);
assertTrue(mapEntryPool.getTotalEntryCount() == 2);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 4096);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255)); //(length - 1) / 16
// acquire new
MapEntry me3 = mapEntryPool.acquire(4100);
assertTrue(me3.getIndex() == 2L); // new
assertTrue(me3.isReleased() == false);
assertTrue(me3.isAllocated() == true);
assertTrue(me3.isInUse() == true);
assertTrue(me3.getSlotSize() == 4100);
assertTrue(mapEntryPool.getFreeEntryCount() == 1);
assertTrue(mapEntryPool.getTotalEntryCount() == 3);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 5124);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 5124);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 4096);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
mapEntryPool.release(me3);
assertTrue(me3.isReleased() == true);
assertTrue(me3.isInUse() == false);
assertTrue(mapEntryPool.getFreeEntryCount() == 2);
assertTrue(mapEntryPool.getTotalEntryCount() == 3);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 8196);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 2);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(256));
assertTrue(me.getIndex() == 0L);
assertTrue(me.isReleased() == false);
assertTrue(me.isAllocated() == true);
assertTrue(me.isInUse() == true);
assertTrue(me.getValueLength() == 1);
assertTrue(me.getSlotSize() == 1024);
mapEntryPool.release(me);
assertTrue(me.isReleased() == true);
assertTrue(me.isInUse() == false);
assertTrue(mapEntryPool.getFreeEntryCount() == 3);
assertTrue(mapEntryPool.getTotalEntryCount() == 3);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 9220);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 1024);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 3);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255)); // (4096 - 1) / 16
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(256));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(63));
// acquire new
me = mapEntryPool.acquire(8192);
assertTrue(me.getIndex() == 3L); // new
assertTrue(me.isReleased() == false);
assertTrue(me.isAllocated() == true);
assertTrue(me.isInUse() == true);
assertTrue(me.getSlotSize() == 8192);
assertTrue(mapEntryPool.getFreeEntryCount() == 3);
assertTrue(mapEntryPool.getTotalEntryCount() == 4);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 8192);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 8192);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 9220);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 1024);
mapEntryPool.release(me);
assertTrue(me.isReleased() == true);
assertTrue(me.isAllocated() == true);
assertTrue(me.isInUse() == false);
// reused exact match
me = mapEntryPool.acquire(1024);
assertTrue(me.getIndex() == 0L); //reused
assertTrue(me.isReleased() == false);
assertTrue(me.isInUse() == true);
assertTrue(me.getSlotSize() == 1024);
assertTrue(mapEntryPool.getFreeEntryCount() == 3);
assertTrue(mapEntryPool.getTotalEntryCount() == 4);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 16388);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((8192 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((8192 - 1) / 16) == 8192);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 3);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(256));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(511));
// cant' reuse within 1025 to 2048
me = mapEntryPool.acquire(1025);
assertTrue(me.getIndex() == 4L); // new
assertTrue(me.isReleased() == false);
assertTrue(me.isInUse() == true);
assertTrue(me.getSlotSize() == 1025);
assertTrue(mapEntryPool.getFreeEntryCount() == 3);
assertTrue(mapEntryPool.getTotalEntryCount() == 5);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 2049);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 2049);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 16388);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((8192 - 1) / 16) == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((8192 - 1) / 16) == 8192);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 3);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(256));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(511));
mapEntryPool.release(me);
assertTrue(me.isReleased() == true);
assertTrue(me.isAllocated() == true);
assertTrue(me.isInUse() == false);
// reuse within 1025 to 2048
me = mapEntryPool.acquire(1024);
assertTrue(me.getIndex() == 4L); // reused
assertTrue(me.isReleased() == false);
assertTrue(me.isInUse() == true);
assertTrue(me.getSlotSize() == 1025);
assertTrue(mapEntryPool.getFreeEntryCount() == 3);
assertTrue(mapEntryPool.getTotalEntryCount() == 5);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 2049);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 2048);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 1);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 16388);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4096 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((4100 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((8192 - 1) / 16) == 1);
assertTrue(mapEntryPool.getFreeEntryCountByIndex(1025) == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4096 - 1) / 16) == 4096);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((4100 - 1) / 16) == 4100);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((8192 - 1) / 16) == 8192);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1025 - 1) / 16) == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 3);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(255));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(256));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(511));
}
@Test
public void TestAcquireInvalidSize() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestAcquireInvalidSize");
try {
mapEntryPool.acquire(MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH + 1);
fail();
} catch (Exception ex) {
// ignore
}
try {
mapEntryPool.acquire(0);
fail();
} catch (Exception ex) {
// ignore
}
// ok
mapEntryPool.acquire(MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH);
mapEntryPool.acquire(1);
}
@Test
public void TestAcquireAndReleaseRandomSize() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestAcquireAndReleaseRandomSize");
int count = 1000;
int maxSize = 1024 * 1024; // 1M
Random random = new Random();
Set<Integer> randomSet = new HashSet<Integer>();
Set<Integer> randomIndexSet = new HashSet<Integer>();
MapEntry[] entries = new MapEntry[count];
for(int i = 0; i < count; i++) {
int size = random.nextInt(maxSize) + 1;
randomSet.add(size);
randomIndexSet.add((size - 1) >> 4); /* (length - 1) / 16 */
entries[i] = mapEntryPool.acquire(size);
}
assertTrue(randomSet.size() <= count);
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == count);
assertTrue(mapEntryPool.getTotalUsedSlotSize() <= maxSize * (long)count);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
for(int i = 0; i < count; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(randomSet.size() <= count);
assertTrue(mapEntryPool.getFreeEntryCount() == count);
assertTrue(mapEntryPool.getTotalEntryCount() == count);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() <= maxSize * (long)count);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == randomIndexSet.size() );
for(int size : randomSet) {
mapEntryPool.getFreeEntryIndexSet().contains(size);
}
}
@Test
public void TestAcquireAndReleaseBigSize() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestAcquireAndReleaseBigSize");
int count = 1000 * 1000;
MapEntry[] entries = new MapEntry[count];
for(int i = 0; i < count; i++) {
entries[i] = mapEntryPool.acquire(MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == count);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH * (long)count);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH * (long)count);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
for(int i = 0; i < count; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == count);
assertTrue(mapEntryPool.getTotalEntryCount() == count);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == MapEntryFactoryImpl.MAX_DATA_SLOT_LENGTH * (long)count);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
}
@Test
public void TestAcquiredAndReleaseDifferentSize() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestAcquiredAndReleaseDifferentSize");
MapEntry[] entries = new MapEntry[10];
for(int i = 0; i < 10; i++) {
entries[i] = mapEntryPool.acquire(1024 * (i + 1));
}
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024 * 55);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024 * 55);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
for(int i = 0; i < 10; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 10);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 1024 * 55);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 10);
for(int i = 0; i < 10; i++) {
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains((1024 * (i + 1) - 1) >> 4)); // (length - 1) / 16
}
}
@Test
public void TestAcquireAndReleaseSameSize() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestAcquireAndReleaseSameSize");
MapEntry[] entries = new MapEntry[10];
for(int i = 0; i < 10; i++) {
entries[i] = mapEntryPool.acquire(1024);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
for(int i = 0; i < 5; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 5);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024 * 5);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 1024 * 5);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 1024 * 5);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 5);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 1024 * 5);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
for(int i = 5; i < 10; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 10);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryCountByIndex((1024 - 1) / 16) == 10);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex((1024 - 1) / 16) == 1024 * 10);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
entries = new MapEntry[10];
for(int i = 0; i < 10; i++) {
entries[i] = mapEntryPool.acquire(513);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 0);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 513 * 10);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 511 * 10);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 0);
for(int i = 0; i < 10; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 10);
assertTrue(mapEntryPool.getTotalEntryCount() == 10);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(63)); // (length - 1) / 16
entries = new MapEntry[10];
for(int i = 0; i < 10; i++) {
entries[i] = mapEntryPool.acquire(128);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 10);
assertTrue(mapEntryPool.getTotalEntryCount() == 20);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 128 * 10);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 128 * 10);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == 1024 * 10);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 1);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(63));
for(int i = 0; i < 10; i++) {
mapEntryPool.release(entries[i]);
}
assertTrue(mapEntryPool.getFreeEntryCount() == 20);
assertTrue(mapEntryPool.getTotalEntryCount() == 20);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() == (1024 + 128) * 10);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().size() == 2);
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(63));
assertTrue(mapEntryPool.getFreeEntryIndexSet().contains(7));
}
@Test
public void TestMultiThreading() throws IOException {
mapEntryPool = new MapEntryFactoryImpl(testDir, "TestMultiThreading");
// init threads and start
int threadNum = 256;
int maxSize = 1024 * 1024 * 4;
int outLoop = 100;
int inLoop = 10;
CountDownLatch latch = new CountDownLatch(threadNum);
Worker[] workers = new Worker[threadNum];
for(int i = 0; i < threadNum; i++) {
workers[i] = new Worker(mapEntryPool, outLoop, inLoop, maxSize, latch);
workers[i].start();
}
// wait to finish
for(int i = 0; i < threadNum; i++) {
try {
workers[i].join();
} catch (InterruptedException e) {
// ignore silently
}
}
assertTrue(mapEntryPool.getFreeEntryIndexSet().headSet(maxSize >> 4).size() > 0);
assertTrue(mapEntryPool.getFreeEntryIndexSet().tailSet(maxSize >> 4).size() == 0);
assertTrue(mapEntryPool.getTotalUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalRealUsedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalWastedSlotSize() == 0);
assertTrue(mapEntryPool.getTotalFreeSlotSize() > 0);
assertTrue(mapEntryPool.getTotalAcquireCounter() == threadNum * outLoop * inLoop);
assertTrue(mapEntryPool.getTotalReleaseCounter() == threadNum * outLoop * inLoop);
assertTrue(mapEntryPool.getTotalAcquireNewCounter() == mapEntryPool.getFreeEntryCount());
System.out.println("mapEntryPool.getFreeEntryIndexSet().size() = " + mapEntryPool.getFreeEntryIndexSet().size());
System.out.println("mapEntryPool.getTotalExatchMatchReuseCounter() = " + mapEntryPool.getTotalExatchMatchReuseCounter());
System.out.println("mapEntryPool.getTotalApproximateMatchReuseCounter() = " + mapEntryPool.getTotalApproximateMatchReuseCounter());
System.out.println("mapEntryPool.getTotalAcquireNewCounter() = " + mapEntryPool.getTotalAcquireNewCounter());
for(int i : mapEntryPool.getFreeEntryIndexSet()) {
assertTrue(mapEntryPool.getFreeEntryCountByIndex(i) > 0);
assertTrue(mapEntryPool.getTotalFreeSlotSizeByIndex(i) > 0);
}
}
private static class Worker extends Thread {
private IMapEntryFactory mapEntryFactory;
private CountDownLatch latch;
private Random random = new Random();
private int outerIteration;
private int innerIteration;
private int maxSize;
public Worker(IMapEntryFactory mapEntryFactory, int outerIteration, int innerIteration,
int maxSize, CountDownLatch latch) {
this.mapEntryFactory = mapEntryFactory;
this.latch = latch;
this.outerIteration = outerIteration;
this.innerIteration = innerIteration;
this.maxSize = maxSize;
}
public void run() {
latch.countDown();
try {
latch.await();
} catch (InterruptedException e1) {
// ignore silently
}
for(int i = 0; i < outerIteration; i++) {
try {
for(int j = 0; j < innerIteration; j++) {
int size = random.nextInt(maxSize) + 1;
MapEntry me = this.mapEntryFactory.acquire(size);
Thread.sleep(random.nextInt(20) + 5);
this.mapEntryFactory.release(me);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@After
public void clear() throws IOException {
if (this.mapEntryPool != null) {
this.mapEntryPool.removeAll();
this.mapEntryPool.close();
}
FileUtil.deleteDirectory(new File(testDir));
}
}