Index: lucene/core/src/java/org/apache/lucene/util/WeakIdentityMap.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/WeakIdentityMap.java (revision 1394156) +++ lucene/core/src/java/org/apache/lucene/util/WeakIdentityMap.java (working copy) @@ -133,22 +133,22 @@ @Override public boolean hasNext() { - return nextIsSet ? true : setNext(); + return nextIsSet || setNext(); } @Override @SuppressWarnings("unchecked") public K next() { - if (nextIsSet || setNext()) { - try { - assert nextIsSet; - return (K) next; - } finally { - // release strong reference and invalidate current value: - nextIsSet = false; - next = null; - } + if (!hasNext()) { + throw new NoSuchElementException(); } - throw new NoSuchElementException(); + assert nextIsSet; + try { + return (K) next; + } finally { + // release strong reference and invalidate current value: + nextIsSet = false; + next = null; + } } @Override @@ -161,14 +161,15 @@ while (iterator.hasNext()) { next = iterator.next().get(); if (next == null) { - // already garbage collected! - continue; + // the key was already GCed, we can remove it from backing map: + iterator.remove(); + } else { + // unfold "null" special value: + if (next == NULL) { + next = null; + } + return nextIsSet = true; } - // unfold "null" special value - if (next == NULL) { - next = null; - } - return nextIsSet = true; } return false; } Index: lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java =================================================================== --- lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java (revision 1394156) +++ lucene/core/src/test/org/apache/lucene/util/TestWeakIdentityMap.java (working copy) @@ -122,13 +122,16 @@ 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 it = map.keyIterator(); it.hasNext();) { assertNotNull(it.next()); c++; } - final int newSize = map.size(); + newSize = map.size(); assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c); assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize); size = newSize; @@ -223,13 +226,16 @@ 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); int c = 0; for (Iterator it = map.keyIterator(); it.hasNext();) { assertNotNull(it.next()); c++; } - final int newSize = map.size(); + newSize = map.size(); assertTrue("previousSize("+size+")>=iteratorSize("+c+")", size >= c); assertTrue("iteratorSize("+c+")>=newSize("+newSize+")", c >= newSize); size = newSize;