@Test @Ignore public void testAcquirePerf() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, InterruptedException { // int runs = Integer.getInteger("runs", 10); for (int runs : new int[] {10, 50, 250, 1000, 2500}) { final long entries = runs * 1000 * 1000L; final SharedHashMap<CharSequence, LongValue> map = getSharedMap(entries * 4 / 3, 1024, 24); int procs = Runtime.getRuntime().availableProcessors(); int threads = procs * 2; int count = runs > 500 ? runs > 1200 ? 1 : 2 : 3; final int independence = Math.min(procs, runs > 500 ? 8 : 4); for (int j = 0; j < count; j++) { long start = System.currentTimeMillis(); ExecutorService es = Executors.newFixedThreadPool(procs); for (int i = 0; i < threads; i++) { final int t = i; es.submit( new Runnable() { @Override public void run() { LongValue value = nativeLongValue(); StringBuilder sb = new StringBuilder(); int next = 50 * 1000 * 1000; // use a factor to give up to 10 digit numbers. int factor = Math.max(1, (int) ((10 * 1000 * 1000 * 1000L - 1) / entries)); for (long i = t % independence; i < entries; i += independence) { sb.setLength(0); sb.append("u:"); sb.append(i * factor); map.acquireUsing(sb, value); long n = value.addAtomicValue(1); assert n >= 0 && n < 1000 : "Counter corrupted " + n; if (t == 0 && i == next) { System.out.println(i); next += 50 * 1000 * 1000; } } } }); } es.shutdown(); es.awaitTermination(runs / 10 + 1, TimeUnit.MINUTES); long time = System.currentTimeMillis() - start; System.out.printf( "Throughput %.1f M ops/sec%n", threads * entries / independence / 1000.0 / time); } printStatus(); map.close(); } }
@Test public void testSize() throws Exception { final SharedHashMap<CharSequence, CharSequence> map = new SharedHashMapBuilder() .minSegments(1024) .removeReturnsNull(true) .create(getPersistenceFile(), CharSequence.class, CharSequence.class); for (int i = 1; i < 1024; i++) { map.put("key" + i, "value"); assertEquals(i, map.size()); } for (int i = 1023; i >= 1; ) { map.remove("key" + i); i--; assertEquals(i, map.size()); } }
@Test public void testAcquireAndGet() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException { int entries = 1000 * 1000; SharedHashMap<CharSequence, LongValue> map = getSharedMap(entries, 128, 24); LongValue value = new LongValueNative(); LongValue value2 = new LongValueNative(); LongValue value3 = new LongValueNative(); for (int j = 1; j <= 3; j++) { for (int i = 0; i < entries; i++) { CharSequence userCS = getUserCharSequence(i); if (j > 1) { assertNotNull(map.getUsing(userCS, value)); } else { map.acquireUsing(userCS, value); } assertEquals(j - 1, value.getValue()); value.addAtomicValue(1); assertEquals(value2, map.acquireUsing(userCS, value2)); assertEquals(j, value2.getValue()); assertEquals(value3, map.getUsing(userCS, value3)); assertEquals(j, value3.getValue()); } } map.close(); }
@Override public void run() { try { LongValue value = new LongValueNative(); barrier.await(); for (int i = 0; i < iterations; i++) { map.acquireUsing(key, value); value.addAtomicValue(1); } } catch (Exception e) { e.printStackTrace(); } }
@Test public void testAcquireFromMultipleThreads() throws Exception { SharedHashMap<CharSequence, LongValue> map = getSharedMap(1000 * 1000, 128, 24); CharSequence key = getUserCharSequence(0); map.acquireUsing(key, new LongValueNative()); int iterations = 1000; int noOfThreads = 10; CyclicBarrier barrier = new CyclicBarrier(noOfThreads); Thread[] threads = new Thread[noOfThreads]; for (int t = 0; t < noOfThreads; t++) { threads[t] = new Thread(new IncrementRunnable(map, key, iterations, barrier)); threads[t].start(); } for (int t = 0; t < noOfThreads; t++) { threads[t].join(); } assertEquals(noOfThreads * iterations, map.acquireUsing(key, new LongValueNative()).getValue()); map.close(); }
@Test public void testPutAndRemove() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException { String TMP = System.getProperty("java.io.tmpdir"); File file = new File(TMP + "/shm-remove-test"); file.delete(); file.deleteOnExit(); int entries = 100 * 1000; SharedHashMap<CharSequence, CharSequence> map = new SharedHashMapBuilder() .entries(entries) .minSegments(16) .entrySize(32) .putReturnsNull(true) .removeReturnsNull(true) .create(file, CharSequence.class, CharSequence.class); StringBuilder key = new StringBuilder(); StringBuilder value = new StringBuilder(); StringBuilder value2 = new StringBuilder(); for (int j = 1; j <= 3; j++) { for (int i = 0; i < entries; i++) { key.setLength(0); key.append("user:"******"value:").append(i); // System.out.println(key); assertNull(map.getUsing(key, value)); assertNull(map.put(key, value)); assertNotNull(map.getUsing(key, value2)); assertEquals(value.toString(), value2.toString()); assertNull(map.remove(key)); assertNull(map.getUsing(key, value)); } } map.close(); }
@Test public void testRemoveWithKey() throws Exception { final SharedHashMap<CharSequence, CharSequence> map = new SharedHashMapBuilder() .minSegments(2) .create(getPersistenceFile(), CharSequence.class, CharSequence.class); assertFalse(map.containsKey("key3")); map.put("key1", "one"); map.put("key2", "two"); assertEquals(2, map.size()); assertTrue(map.containsKey("key1")); assertTrue(map.containsKey("key2")); assertFalse(map.containsKey("key3")); assertEquals("one", map.get("key1")); assertEquals("two", map.get("key2")); final CharSequence result = map.remove("key1"); assertEquals(1, map.size()); assertEquals("one", result); assertFalse(map.containsKey("key1")); assertEquals(null, map.get("key1")); assertEquals("two", map.get("key2")); assertFalse(map.containsKey("key3")); // lets add one more item for luck ! map.put("key3", "three"); assertEquals("three", map.get("key3")); assertTrue(map.containsKey("key3")); assertEquals(2, map.size()); // and just for kicks we'll overwrite what we have map.put("key3", "overwritten"); assertEquals("overwritten", map.get("key3")); assertTrue(map.containsKey("key3")); assertEquals(2, map.size()); }
@Test public void testGetWithoutAcquireFirst() throws Exception { SharedHashMap<CharSequence, LongValue> map = getSharedMap(10 * 1000, 128, 24); assertNull(map.getUsing("key", new LongValueNative())); }
@Test public void testGetWithNullContainer() throws Exception { SharedHashMap<CharSequence, LongValue> map = getSharedMap(10 * 1000, 128, 24); map.acquireUsing("key", new LongValueNative()); assertEquals(0, map.getUsing("key", null).getValue()); }
@Test public void testGetWithNullKey() throws Exception { SharedHashMap<CharSequence, LongValue> map = getSharedMap(10 * 1000, 128, 24); assertNull(map.getUsing(null, new LongValueNative())); }
@Test public void testRemoveWithKeyAndValue() throws Exception { final SharedHashMap<CharSequence, CharSequence> map = new SharedHashMapBuilder() .minSegments(2) .create(getPersistenceFile(), CharSequence.class, CharSequence.class); map.put("key1", "one"); map.put("key2", "two"); assertEquals("one", map.get("key1")); assertEquals("two", map.get("key2")); // a false remove final boolean wasRemoved1 = map.remove("key1", "three"); assertFalse(wasRemoved1); assertEquals(null, map.get("key1"), "one"); assertEquals("two", map.get("key2"), "two"); map.put("key1", "one"); final boolean wasRemoved2 = map.remove("key1", "three"); assertFalse(wasRemoved2); // lets add one more item for luck ! map.put("key3", "three"); assertEquals("three", map.get("key3")); // and just for kicks we'll overwrite what we have map.put("key3", "overwritten"); assertEquals("overwritten", map.get("key3")); }
@Test public void testReplaceWithKeyAnd2Params() throws Exception { final SharedHashMap<CharSequence, CharSequence> map = new SharedHashMapBuilder() .minSegments(2) .create(getPersistenceFile(), CharSequence.class, CharSequence.class); map.put("key1", "one"); map.put("key2", "two"); assertEquals("one", map.get("key1")); assertEquals("two", map.get("key2")); final boolean result = map.replace("key1", "one", "newValue"); assertEquals(true, result); assertEquals("newValue", map.get("key1")); assertEquals("two", map.get("key2")); // let and one more item for luck ! map.put("key3", "three"); assertEquals("three", map.get("key3")); // and just for kicks we'll overwrite what we have map.put("key3", "overwritten"); assertEquals("overwritten", map.get("key3")); final boolean result2 = map.replace("key2", "two", "newValue2"); assertEquals(true, result2); assertEquals("newValue2", map.get("key2")); final boolean result3 = map.replace("newKey", "", "newValue"); assertEquals(false, result3); final boolean result4 = map.replace("key2", "newValue2", "newValue2"); assertEquals(true, result4); }