// Concurrent insertion & then iterator test.
  public static void testNonBlockingIdentityHashMapIterator() throws InterruptedException {
    final int ITEM_COUNT1 = 1000;
    final int THREAD_COUNT = 5;
    final int PER_CNT = ITEM_COUNT1 / THREAD_COUNT;
    final int ITEM_COUNT = PER_CNT * THREAD_COUNT; // fix roundoff for odd thread counts

    NonBlockingIdentityHashMap<Long, TestKey> nbhml =
        new NonBlockingIdentityHashMap<Long, TestKey>();
    // use a barrier to open the gate for all threads at once to avoid rolling
    // start and no actual concurrency
    final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT);
    final ExecutorService ex = Executors.newFixedThreadPool(THREAD_COUNT);
    final CompletionService<Object> co = new ExecutorCompletionService<Object>(ex);
    for (int i = 0; i < THREAD_COUNT; i++) {
      co.submit(new NBHMLFeeder(nbhml, PER_CNT, barrier, i * PER_CNT));
    }
    for (int retCount = 0; retCount < THREAD_COUNT; retCount++) {
      co.take();
    }
    ex.shutdown();

    assertEquals("values().size()", ITEM_COUNT, nbhml.values().size());
    assertEquals("entrySet().size()", ITEM_COUNT, nbhml.entrySet().size());
    int itemCount = 0;
    for (TestKey K : nbhml.values()) itemCount++;
    assertEquals("values().iterator() count", ITEM_COUNT, itemCount);
  }
  public final void testNonBlockingIdentityHashMapSize() {
    NonBlockingIdentityHashMap<Long, String> items = new NonBlockingIdentityHashMap<Long, String>();
    items.put(Long.valueOf(100), "100");
    items.put(Long.valueOf(101), "101");

    assertEquals("keySet().size()", 2, items.keySet().size());
    assertTrue("keySet().contains(100)", items.keySet().contains(Long.valueOf(100)));
    assertTrue("keySet().contains(101)", items.keySet().contains(Long.valueOf(101)));

    assertEquals("values().size()", 2, items.values().size());
    assertTrue("values().contains(\"100\")", items.values().contains("100"));
    assertTrue("values().contains(\"101\")", items.values().contains("101"));

    assertEquals("entrySet().size()", 2, items.entrySet().size());
    boolean found100 = false;
    boolean found101 = false;
    for (Entry<Long, String> entry : items.entrySet()) {
      if (entry.getKey().equals(Long.valueOf(100))) {
        assertEquals("entry[100].getValue()==\"100\"", "100", entry.getValue());
        found100 = true;
      } else if (entry.getKey().equals(Long.valueOf(101))) {
        assertEquals("entry[101].getValue()==\"101\"", "101", entry.getValue());
        found101 = true;
      }
    }
    assertTrue("entrySet().contains([100])", found100);
    assertTrue("entrySet().contains([101])", found101);
  }
  public void testIteration() {
    assertTrue(_nbhm.isEmpty());
    assertThat(_nbhm.put("k1", "v1"), nullValue());
    assertThat(_nbhm.put("k2", "v2"), nullValue());

    String str1 = "";
    for (Iterator<Map.Entry<String, String>> i = _nbhm.entrySet().iterator(); i.hasNext(); ) {
      Map.Entry<String, String> e = i.next();
      str1 += e.getKey();
    }
    assertThat("found all entries", str1, anyOf(is("k1k2"), is("k2k1")));

    String str2 = "";
    for (Iterator<String> i = _nbhm.keySet().iterator(); i.hasNext(); ) {
      String key = i.next();
      str2 += key;
    }
    assertThat("found all keys", str2, anyOf(is("k1k2"), is("k2k1")));

    String str3 = "";
    for (Iterator<String> i = _nbhm.values().iterator(); i.hasNext(); ) {
      String val = i.next();
      str3 += val;
    }
    assertThat("found all vals", str3, anyOf(is("v1v2"), is("v2v1")));

    assertThat(
        "toString works", _nbhm.toString(), anyOf(is("{k1=v1, k2=v2}"), is("{k2=v2, k1=v1}")));
  }
 // Check all iterators for correct size counts
 private void checkSizes(int expectedSize) {
   assertEquals("size()", _nbhm.size(), expectedSize);
   Collection<String> vals = _nbhm.values();
   checkSizes("values()", vals.size(), vals.iterator(), expectedSize);
   Set<String> keys = _nbhm.keySet();
   checkSizes("keySet()", keys.size(), keys.iterator(), expectedSize);
   Set<Entry<String, String>> ents = _nbhm.entrySet();
   checkSizes("entrySet()", ents.size(), ents.iterator(), expectedSize);
 }
  // ---
  public void testNonBlockingIdentityHashMapIteratorMultithreaded()
      throws InterruptedException, ExecutionException {
    TestKeyFeeder feeder = getTestKeyFeeder();
    final int itemCount = feeder.size();

    // validate results
    final NonBlockingIdentityHashMap<Long, TestKey> items = feeder.getMapMultithreaded();
    assertEquals("size()", itemCount, items.size());

    assertEquals("values().size()", itemCount, items.values().size());

    assertEquals("entrySet().size()", itemCount, items.entrySet().size());

    int iteratorCount = 0;
    for (TestKey m : items.values()) iteratorCount++;
    // sometimes a different result comes back the second time
    int iteratorCount2 = 0;
    for (Iterator<TestKey> it = items.values().iterator(); it.hasNext(); ) {
      iteratorCount2++;
      it.next();
    }
    assertEquals("iterator counts differ", iteratorCount, iteratorCount2);
    assertEquals("values().iterator() count", itemCount, iteratorCount);
  }