@Test
  public void testPutRemoveGetMany() {
    final long factor = 123456;
    final int k = 5000;
    final int mod = 100;

    for (int i = 1; i <= k; i++) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      assertTrue(hsa.ensure(key1, key2) > 0);
    }

    for (int i = mod; i <= k; i += mod) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      assertTrue(hsa.remove(key1, key2));
    }

    for (int i = 1; i <= k; i++) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      long valueAddress = hsa.get(key1, key2);

      if (i % mod == 0) {
        assertEquals(NULL_ADDRESS, valueAddress);
      } else {
        assertNotEquals(NULL_ADDRESS, valueAddress);
      }
    }
  }
 @Test(expected = AssertionError.class)
 @RequireAssertEnabled
 public void testCursor_valueAddress_whenDisposed() {
   HashSlotCursor16byteKey cursor = hsa.cursor();
   hsa.dispose();
   cursor.valueAddress();
 }
  @Test
  public void testCursor_withManyValues() {
    final long factor = 123456;
    final int k = 1000;

    for (int i = 1; i <= k; i++) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      hsa.ensure(key1, key2);
    }

    boolean[] verifyKeys = new boolean[k];
    Arrays.fill(verifyKeys, false);

    HashSlotCursor16byteKey cursor = hsa.cursor();
    while (cursor.advance()) {
      long key1 = cursor.key1();
      long key2 = cursor.key2();

      assertEquals(key1 * factor, key2);
      verifyKeys[((int) key1) - 1] = true;
    }

    for (int i = 0; i < k; i++) {
      assertTrue("Haven't read " + k + "th key!", verifyKeys[i]);
    }
  }
  @Test
  public void testCursor_advance() {
    hsa.ensure(randomKey(), randomKey());

    HashSlotCursor16byteKey cursor = hsa.cursor();
    assertTrue(cursor.advance());
    assertFalse(cursor.advance());
  }
  @Test
  public void testCursor_valueAddress() {
    final long valueAddress = hsa.ensure(randomKey(), randomKey());

    HashSlotCursor16byteKey cursor = hsa.cursor();
    cursor.advance();
    assertEquals(valueAddress, cursor.valueAddress());
  }
  @Test
  public void testGet() throws Exception {
    final long key1 = randomKey();
    final long key2 = randomKey();
    final long valueAddress = hsa.ensure(key1, key2);

    final long valueAddress2 = hsa.get(key1, key2);
    assertEquals(valueAddress, valueAddress2);
  }
  @Test
  public void testRemove() throws Exception {
    final long key1 = randomKey();
    final long key2 = randomKey();
    hsa.ensure(key1, key2);

    assertTrue(hsa.remove(key1, key2));
    assertFalse(hsa.remove(key1, key2));
  }
  @Test
  public void testPut() throws Exception {
    final long key1 = randomKey();
    final long key2 = randomKey();
    final long valueAddress = hsa.ensure(key1, key2);
    assertNotEquals(NULL_ADDRESS, valueAddress);

    final long valueAddress2 = hsa.ensure(key1, key2);
    assertEquals(valueAddress, -valueAddress2);
  }
  @Test
  public void testCursor_key2() {
    final long key1 = randomKey();
    final long key2 = randomKey();
    hsa.ensure(key1, key2);

    HashSlotCursor16byteKey cursor = hsa.cursor();
    cursor.advance();
    assertEquals(key2, cursor.key2());
  }
  @Test
  public void testSize() throws Exception {
    final long key1 = randomKey();
    final long key2 = randomKey();

    hsa.ensure(key1, key2);
    assertEquals(1, hsa.size());

    assertTrue(hsa.remove(key1, key2));
    assertEquals(0, hsa.size());
  }
  @Test
  public void testClear() throws Exception {
    final long key1 = randomKey();
    final long key2 = randomKey();

    hsa.ensure(key1, key2);
    hsa.clear();

    assertEquals(NULL_ADDRESS, hsa.get(key1, key2));
    assertEquals(0, hsa.size());
  }
  @Test
  public void testCursor_advance_afterAdvanceReturnsFalse() {
    hsa.ensure(randomKey(), randomKey());

    HashSlotCursor16byteKey cursor = hsa.cursor();
    cursor.advance();
    cursor.advance();

    try {
      cursor.advance();
      fail("cursor.advance() returned false, but subsequent call did not throw AssertionError");
    } catch (AssertionError ignored) {
    }
  }
  @Test
  public void testPutGetMany() {
    final long factor = 123456;
    final int k = 1000;

    for (int i = 1; i <= k; i++) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      assertTrue(hsa.ensure(key1, key2) > 0);
    }

    for (int i = 1; i <= k; i++) {
      long key1 = (long) i;
      long key2 = key1 * factor;
      assertNotEquals(NULL_ADDRESS, hsa.get(key1, key2));
    }
  }
 @Test(expected = AssertionError.class)
 @RequireAssertEnabled
 public void testRemove_whenDisposed() throws Exception {
   hsa.dispose();
   hsa.remove(1, 1);
 }
 @Test(expected = AssertionError.class)
 @RequireAssertEnabled
 public void testClear_whenDisposed() throws Exception {
   hsa.dispose();
   hsa.clear();
 }
 @Test(expected = AssertionError.class)
 @RequireAssertEnabled
 public void testCursor_valueAddress_withoutAdvance() {
   HashSlotCursor16byteKey cursor = hsa.cursor();
   cursor.valueAddress();
 }
 @After
 public void tearDown() throws Exception {
   hsa.dispose();
   memMgr.dispose();
 }
 @Before
 public void setUp() throws Exception {
   memMgr = new HeapMemoryManager(32 << 20);
   hsa = new HashSlotArray16byteKeyNoValue(0L, memMgr);
   hsa.gotoNew();
 }
 @Test
 public void testCursor_advance_whenEmpty() {
   HashSlotCursor16byteKey cursor = hsa.cursor();
   assertFalse(cursor.advance());
 }