@Override
  public final void close() throws IOException {
    try {
      if (buffers == null) return;

      // make local copy, then un-set early
      final ByteBuffer[] bufs = buffers;
      unsetBuffers();
      if (clones != null) {
        clones.remove(this);
      }

      if (isClone) return;

      // for extra safety unset also all clones' buffers:
      if (clones != null) {
        for (Iterator<ByteBufferIndexInput> it = this.clones.keyIterator(); it.hasNext(); ) {
          final ByteBufferIndexInput clone = it.next();
          assert clone.isClone;
          clone.unsetBuffers();
        }
        this.clones.clear();
      }

      for (final ByteBuffer b : bufs) {
        freeBuffer(b);
      }
    } finally {
      unsetBuffers();
    }
  }
예제 #2
0
  public void testSimpleHashMap() {
    final WeakIdentityMap<String, String> map = WeakIdentityMap.newHashMap(random().nextBoolean());
    // we keep strong references to the keys,
    // so WeakIdentityMap will not forget about them:
    String key1 = new String("foo");
    String key2 = new String("foo");
    String key3 = new String("foo");

    assertNotSame(key1, key2);
    assertEquals(key1, key2);
    assertNotSame(key1, key3);
    assertEquals(key1, key3);
    assertNotSame(key2, key3);
    assertEquals(key2, key3);

    // try null key & check its iterator also return null:
    map.put(null, "null");
    {
      Iterator<String> it = map.keyIterator();
      assertTrue(it.hasNext());
      assertNull(it.next());
      assertFalse(it.hasNext());
      assertFalse(it.hasNext());
    }
    // 2 more keys:
    map.put(key1, "bar1");
    map.put(key2, "bar2");

    assertEquals(3, map.size());

    assertEquals("bar1", map.get(key1));
    assertEquals("bar2", map.get(key2));
    assertEquals(null, map.get(key3));
    assertEquals("null", map.get(null));

    assertTrue(map.containsKey(key1));
    assertTrue(map.containsKey(key2));
    assertFalse(map.containsKey(key3));
    assertTrue(map.containsKey(null));

    // repeat and check that we have no double entries
    map.put(key1, "bar1");
    map.put(key2, "bar2");
    map.put(null, "null");

    assertEquals(3, map.size());

    assertEquals("bar1", map.get(key1));
    assertEquals("bar2", map.get(key2));
    assertEquals(null, map.get(key3));
    assertEquals("null", map.get(null));

    assertTrue(map.containsKey(key1));
    assertTrue(map.containsKey(key2));
    assertFalse(map.containsKey(key3));
    assertTrue(map.containsKey(null));

    map.remove(null);
    assertEquals(2, map.size());
    map.remove(key1);
    assertEquals(1, map.size());
    map.put(key1, "bar1");
    map.put(key2, "bar2");
    map.put(key3, "bar3");
    assertEquals(3, map.size());

    int c = 0, keysAssigned = 0;
    for (Iterator<String> it = map.keyIterator(); it.hasNext(); ) {
      assertTrue(it.hasNext()); // try again, should return same result!
      final String k = it.next();
      assertTrue(k == key1 || k == key2 | k == key3);
      keysAssigned += (k == key1) ? 1 : ((k == key2) ? 2 : 4);
      c++;
    }
    assertEquals(3, c);
    assertEquals("all keys must have been seen", 1 + 2 + 4, keysAssigned);

    c = 0;
    for (Iterator<String> it = map.valueIterator(); it.hasNext(); ) {
      final String v = it.next();
      assertTrue(v.startsWith("bar"));
      c++;
    }
    assertEquals(3, c);

    // clear strong refs
    key1 = key2 = key3 = null;

    // check that GC does not cause problems in reap() method, wait 1 second and let GC work:
    int size = map.size();
    for (int i = 0; size > 0 && i < 10; i++)
      try {
        System.runFinalization();
        System.gc();
        int newSize = map.size();
        assertTrue("previousSize(" + size + ")>=newSize(" + newSize + ")", size >= newSize);
        size = newSize;
        Thread.sleep(100L);
        c = 0;
        for (Iterator<String> it = map.keyIterator(); it.hasNext(); ) {
          assertNotNull(it.next());
          c++;
        }
        newSize = map.size();
        assertTrue("previousSize(" + size + ")>=iteratorSize(" + c + ")", size >= c);
        assertTrue("iteratorSize(" + c + ")>=newSize(" + newSize + ")", c >= newSize);
        size = newSize;
      } catch (InterruptedException ie) {
      }

    map.clear();
    assertEquals(0, map.size());
    assertTrue(map.isEmpty());

    Iterator<String> it = map.keyIterator();
    assertFalse(it.hasNext());
    try {
      it.next();
      fail("Should throw NoSuchElementException");
    } catch (NoSuchElementException nse) {
    }

    key1 = new String("foo");
    key2 = new String("foo");
    map.put(key1, "bar1");
    map.put(key2, "bar2");
    assertEquals(2, map.size());

    map.clear();
    assertEquals(0, map.size());
    assertTrue(map.isEmpty());
  }