package net.yadan.banana.map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import net.yadan.banana.DebugLevel; import net.yadan.banana.memory.IMemAllocator; import net.yadan.banana.memory.initializers.MemSetInitializer; import net.yadan.banana.memory.malloc.ChainedAllocator; import org.junit.Test; public class HashMapTest { private static final int BLOCK_SIZE = 10; protected IHashMap create(int initialCapacity, double loadFactor) { IMemAllocator allocator = new ChainedAllocator(100, HashMap.RESERVED_SIZE + BLOCK_SIZE, 2.0); allocator.setDebug(true); allocator.setInitializer(new MemSetInitializer(-1)); HashMap map = new HashMap(allocator, initialCapacity, loadFactor); map.setDebug(DebugLevel.DEBUG_STRUCTURE); return map; } @Test public void testHashMapIntFloat() { IHashMap h = create(10, 0.75f); assertEquals(10, h.getCapacity()); assertEquals(0.75f, h.getLoadFactor(), Float.MIN_VALUE); } @Test public void testSizeAfterAdd() { IHashMap h = create(20, 1.0); for (int i = 1; i <= 20; i++) { h.createRecord(i, BLOCK_SIZE); assertEquals(i, h.size()); } } @Test public void testSizeAfterRemove() { IHashMap h = create(20, 1.0); for (int i = 1; i <= 20; i++) { h.createRecord(i, BLOCK_SIZE); } assertEquals(20, h.size()); for (int i = 1; i <= 20; i++) { h.remove(i); assertEquals(20 - i, h.size()); } } @Test public void testPutRecord() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); assertEquals(-1, h.findRecord(100)); assertEquals(pointer, h.findRecord(1000)); } @Test public void testPutRecordWithSameKey() { IHashMap h = create(10, 0.75f); h.setDebug(DebugLevel.DEBUG_STRUCTURE); IMemAllocator mem = h.getAllocator(); mem.setInitializer(new MemSetInitializer(0)); assertEquals(0, mem.usedBlocks()); int pointer1 = h.createRecord(1000, BLOCK_SIZE); assertEquals(pointer1, h.findRecord(1000)); assertEquals(1, mem.usedBlocks()); h.setInt(pointer1, 0, 19); int pointer2 = h.createRecord(1000, BLOCK_SIZE); assertEquals(0, h.getInt(pointer2, 0)); h.setInt(pointer2, 0, 29); assertEquals(pointer2, h.findRecord(1000)); assertEquals(1, mem.usedBlocks()); assertEquals(1, h.size()); } @Test public void testIsEmpty() { IHashMap h = create(10, 0.75f); assertTrue(h.isEmpty()); h.createRecord(10, BLOCK_SIZE); assertFalse(h.isEmpty()); } @Test public void testContainsKey() { IHashMap h = create(10, 0.75f); assertFalse(h.containsKey(100)); h.createRecord(100, BLOCK_SIZE); assertTrue(h.containsKey(100)); } @Test public void testLongData() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); h.setLong(pointer, 0, Long.MAX_VALUE); assertEquals(Long.MAX_VALUE, h.getLong(pointer, 0)); h.setLong(pointer, 0, 800); assertEquals(800, h.getLong(pointer, 0)); } @Test public void testIntData() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); h.setInt(pointer, 0, Integer.MAX_VALUE); assertEquals(Integer.MAX_VALUE, h.getInt(pointer, 0)); h.setInt(pointer, 1, 800); assertEquals(800, h.getInt(pointer, 1)); } @Test public void testFloatData() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); h.setFloat(pointer, 0, 9999); assertEquals(9999, h.getFloat(pointer, 0), Float.MIN_VALUE); h.setFloat(pointer, 1, 800); assertEquals(800, h.getFloat(pointer, 1), Float.MIN_VALUE); } @Test public void testDoubleData() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); h.setDouble(pointer, 0, 9999); assertEquals(9999, h.getDouble(pointer, 0), Double.MIN_VALUE); h.setDouble(pointer, 2, 800); assertEquals(800, h.getDouble(pointer, 2), Double.MIN_VALUE); } @Test public void testRemove() { IHashMap h = create(10, 0.75f); int pointer = h.createRecord(1000, BLOCK_SIZE); assertEquals(pointer, h.findRecord(1000)); assertEquals(1, h.size()); h.remove(1000); assertEquals(0, h.size()); } @Test public void testClear() { IHashMap h = create(10, 0.75f); assertEquals(0, h.size()); for (int i = 1; i <= 20; i++) { h.createRecord(i, BLOCK_SIZE); } h.clear(); assertEquals(0, h.size()); } @Test public void testHashKeyOverflow() { IHashMap h = create(100000, 0.75f); h.createRecord(100003995712499L, BLOCK_SIZE); } @Test public void testGrowth() { IHashMap h = create(7, 0.8); for (int i = 0; i < 5; i++) { int n = h.createRecord(i * i * i + 2, BLOCK_SIZE); h.setInt(n, 0, i); } int n = h.createRecord(5 * 5 * 5 + 2, BLOCK_SIZE); h.setInt(n, 0, 5); assertEquals(6, h.size()); for (int i = 0; i < h.size(); i++) { assertEquals(i, h.getInt(h.findRecord(i * i * i + 2), 0)); } } @Test public void testReallocRecord() { IHashMap h = create(10, 0.8); for (int i = 0; i < 10; i++) { int r = h.createRecord(i * i, 1); // System.out.println(h.getAllocator().pointerDebugString(r)); h.setInt(r, 0, i); } for (int i = 0; i < 10; i++) { int r = h.reallocRecord(i * i, 15); h.setInt(r, 10, i); // System.out.println(h.getAllocator().pointerDebugString(r)); } } @Test public void testCreateSameRecordDifferentSize() { IHashMap h = create(10, 0.8); h.createRecord(1000, BLOCK_SIZE); int size = BLOCK_SIZE * 2; int r = h.createRecord(1000, size); h.setInts(r, 0, new int[size], 0, size); } }