@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);
  }