package com.github.hoffart.dmap.test; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import com.github.hoffart.dmap.DMap; import com.github.hoffart.dmap.util.ByteUtils; import com.github.hoffart.dmap.DMapBuilder; import org.junit.Test; public class DMapTest { @Test public void testDMapWithValueCompression() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256, true); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile).build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void testDMapWithOffsetsPreloadingAndValueCompression() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256, true); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void testDMapWitFullPreloadingAndValueCompression() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256, true); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .preloadValues() .build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void testDMapWithoutPreloadingOffsets() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile).build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void testDMapWithOffsetsPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void testDMapWitFullPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .preloadValues() .build(); for (int i = 0; i < count; ++i) { byte[] value = dmap.get(ByteUtils.getBytes(i)); assertEquals(i, ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void randomTestWithOffsetPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; Random r = new Random(); Map<Integer, Integer> kvs = new HashMap<>(); for (int i = 0; i < count; ++i) { int k = r.nextInt(); int v = r.nextInt(); kvs.put(k, v); dmapBuilder.add(ByteUtils.getBytes(k), ByteUtils.getBytes(v)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .build(); for (Entry<Integer, Integer> e : kvs.entrySet()) { byte[] value = dmap.get(ByteUtils.getBytes(e.getKey())); assertEquals(e.getValue().intValue(), ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void randomTestWithoutOffsetPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; Random r = new Random(); Map<Integer, Integer> kvs = new HashMap<>(); for (int i = 0; i < count; ++i) { int k = r.nextInt(); int v = r.nextInt(); kvs.put(k, v); dmapBuilder.add(ByteUtils.getBytes(k), ByteUtils.getBytes(v)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile).build(); for (Entry<Integer, Integer> e : kvs.entrySet()) { byte[] value = dmap.get(ByteUtils.getBytes(e.getKey())); assertEquals(e.getValue().intValue(), ByteBuffer.wrap(value).getInt()); } assertEquals(null, dmap.get(ByteUtils.getBytes(count + 1))); assertEquals(null, dmap.get(ByteUtils.getBytes(-1))); tmpFile.delete(); } @Test public void multiThreadTestWithOffsetPreloading() throws IOException, InterruptedException, ExecutionException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; Random r = new Random(); Map<Integer, Integer> kvs = new HashMap<>(); for (int i = 0; i < count; ++i) { int k = r.nextInt(); int v = r.nextInt(); kvs.put(k, v); dmapBuilder.add(ByteUtils.getBytes(k), ByteUtils.getBytes(v)); } dmapBuilder.build(); int threadCount = 100; ExecutorService es = Executors.newFixedThreadPool(threadCount); List<Future<Boolean>> results = new ArrayList<>(100); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .build(); for (int t = 0; t < threadCount; ++t) { Reader reader = new Reader(dmap, kvs); Future<Boolean> result = es.submit(reader); results.add(result); } for (Future<Boolean> result : results) { assertTrue(result.get()); } tmpFile.delete(); } @Test public void multiThreadTestWithoutOffsetPreloading() throws IOException, InterruptedException, ExecutionException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; Random r = new Random(); Map<Integer, Integer> kvs = new HashMap<>(); for (int i = 0; i < count; ++i) { int k = r.nextInt(); int v = r.nextInt(); kvs.put(k, v); dmapBuilder.add(ByteUtils.getBytes(k), ByteUtils.getBytes(v)); } dmapBuilder.build(); int threadCount = 100; ExecutorService es = Executors.newFixedThreadPool(threadCount); List<Future<Boolean>> results = new ArrayList<>(100); DMap dmap = new DMap.Builder(tmpFile).build(); for (int t = 0; t < threadCount; ++t) { Reader reader = new Reader(dmap, kvs); Future<Boolean> result = es.submit(reader); results.add(result); } for (Future<Boolean> result : results) { assertTrue(result.get()); } tmpFile.delete(); } @Test public void iteratorWithKeyPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .build(); boolean[] keysReturned = new boolean[count]; DMap.EntryIterator entryIterator = dmap.entryIterator(); while (entryIterator.hasNext()) { DMap.Entry entry = entryIterator.next(); keysReturned[ByteBuffer.wrap(entry.getKey()).getInt()] = true; assertEquals(ByteBuffer.wrap(entry.getKey()).getInt(), ByteBuffer.wrap(entry.getValue()).getInt()); } for (boolean b : keysReturned) { assertTrue(b); } tmpFile.delete(); } @Test public void iteratorWithoutPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .build(); boolean[] keysReturned = new boolean[count]; DMap.EntryIterator entryIterator = dmap.entryIterator(); while (entryIterator.hasNext()) { DMap.Entry entry = entryIterator.next(); keysReturned[ByteBuffer.wrap(entry.getKey()).getInt()] = true; assertEquals(ByteBuffer.wrap(entry.getKey()).getInt(), ByteBuffer.wrap(entry.getValue()).getInt()); } for (boolean b : keysReturned) { assertTrue(b); } tmpFile.delete(); } @Test public void iteratorWithFullPreloading() throws IOException { File tmpFile = File.createTempFile("tmp", ".dmap"); tmpFile.delete(); DMapBuilder dmapBuilder = new DMapBuilder(tmpFile, 256); int count = 1 << 10; for (int i = 0; i < count; ++i) { dmapBuilder.add(ByteUtils.getBytes(i), ByteUtils.getBytes(i)); } dmapBuilder.build(); DMap dmap = new DMap.Builder(tmpFile) .preloadOffsets() .preloadValues() .build(); boolean[] keysReturned = new boolean[count]; DMap.EntryIterator entryIterator = dmap.entryIterator(); while (entryIterator.hasNext()) { DMap.Entry entry = entryIterator.next(); keysReturned[ByteBuffer.wrap(entry.getKey()).getInt()] = true; assertEquals(ByteBuffer.wrap(entry.getKey()).getInt(), ByteBuffer.wrap(entry.getValue()).getInt()); } for (boolean b : keysReturned) { assertTrue(b); } tmpFile.delete(); } private class Reader implements Callable<Boolean> { private DMap dmap_; private Map<Integer, Integer> toRead_; private Reader(DMap dmap, Map<Integer, Integer> toRead) { dmap_ = dmap; toRead_ = toRead; } @Override public Boolean call() throws Exception { for (Entry<Integer, Integer> e : toRead_.entrySet()) { byte[] value = dmap_.get(ByteUtils.getBytes(e.getKey())); if (e.getValue() != ByteBuffer.wrap(value).getInt()) { return false; } } // Everything was correct. return true; } } }