Index: lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java (revision 1448313) +++ lucene/core/src/java/org/apache/lucene/index/DocTermOrds.java (working copy) @@ -173,30 +173,29 @@ } /** Inverts all terms */ - public DocTermOrds(AtomicReader reader, String field) throws IOException { - this(reader, field, null, Integer.MAX_VALUE); + public DocTermOrds(AtomicReader reader, Bits liveDocs, String field) throws IOException { + this(reader, liveDocs, field, null, Integer.MAX_VALUE); } /** Inverts only terms starting w/ prefix */ - public DocTermOrds(AtomicReader reader, String field, BytesRef termPrefix) throws IOException { - this(reader, field, termPrefix, Integer.MAX_VALUE); + public DocTermOrds(AtomicReader reader, Bits liveDocs, String field, BytesRef termPrefix) throws IOException { + this(reader, liveDocs, field, termPrefix, Integer.MAX_VALUE); } /** Inverts only terms starting w/ prefix, and only terms * whose docFreq (not taking deletions into account) is * <= maxTermDocFreq */ - public DocTermOrds(AtomicReader reader, String field, BytesRef termPrefix, int maxTermDocFreq) throws IOException { - this(reader, field, termPrefix, maxTermDocFreq, DEFAULT_INDEX_INTERVAL_BITS); - uninvert(reader, termPrefix); + public DocTermOrds(AtomicReader reader, Bits liveDocs, String field, BytesRef termPrefix, int maxTermDocFreq) throws IOException { + this(reader, liveDocs, field, termPrefix, maxTermDocFreq, DEFAULT_INDEX_INTERVAL_BITS); } /** Inverts only terms starting w/ prefix, and only terms * whose docFreq (not taking deletions into account) is * <= maxTermDocFreq, with a custom indexing interval * (default is every 128nd term). */ - public DocTermOrds(AtomicReader reader, String field, BytesRef termPrefix, int maxTermDocFreq, int indexIntervalBits) throws IOException { + public DocTermOrds(AtomicReader reader, Bits liveDocs, String field, BytesRef termPrefix, int maxTermDocFreq, int indexIntervalBits) throws IOException { this(field, maxTermDocFreq, indexIntervalBits); - uninvert(reader, termPrefix); + uninvert(reader, liveDocs, termPrefix); } /** Subclass inits w/ this, but be sure you then call @@ -257,14 +256,14 @@ protected void visitTerm(TermsEnum te, int termNum) throws IOException { } - /** Invoked during {@link #uninvert(AtomicReader,BytesRef)} + /** Invoked during {@link #uninvert(AtomicReader,Bits,BytesRef)} * to record the document frequency for each uninverted * term. */ protected void setActualDocFreq(int termNum, int df) throws IOException { } /** Call this only once (if you subclass!) */ - protected void uninvert(final AtomicReader reader, final BytesRef termPrefix) throws IOException { + protected void uninvert(final AtomicReader reader, Bits liveDocs, final BytesRef termPrefix) throws IOException { final FieldInfo info = reader.getFieldInfos().fieldInfo(field); if (info != null && info.hasDocValues()) { throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType()); @@ -304,8 +303,6 @@ boolean testedOrd = false; - final Bits liveDocs = reader.getLiveDocs(); - // we need a minimum of 9 bytes, but round up to 12 since the space would // be wasted with most allocators anyway. byte[] tempArr = new byte[12]; Index: lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java (revision 1448313) +++ lucene/core/src/java/org/apache/lucene/search/FieldCacheImpl.java (working copy) @@ -1399,7 +1399,7 @@ @Override protected Object createValue(AtomicReader reader, CacheKey key, boolean setDocsWithField /* ignored */) throws IOException { - return new DocTermOrds(reader, key.field); + return new DocTermOrds(reader, null, key.field); } } Index: lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java =================================================================== --- lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java (revision 1448313) +++ lucene/core/src/test/org/apache/lucene/index/TestDocTermOrds.java (working copy) @@ -63,7 +63,7 @@ w.close(); final AtomicReader ar = SlowCompositeReaderWrapper.wrap(r); - final DocTermOrds dto = new DocTermOrds(ar, "field"); + final DocTermOrds dto = new DocTermOrds(ar, ar.getLiveDocs(), "field"); SortedSetDocValues iter = dto.iterator(ar.terms("field").iterator(null)); iter.setDocument(0); @@ -295,7 +295,7 @@ private void verify(AtomicReader r, int[][] idToOrds, BytesRef[] termsArray, BytesRef prefixRef) throws Exception { - final DocTermOrds dto = new DocTermOrds(r, + final DocTermOrds dto = new DocTermOrds(r, r.getLiveDocs(), "field", prefixRef, Integer.MAX_VALUE, @@ -372,4 +372,34 @@ assertEquals(answers.length, upto); } } + + public void testBackToTheFuture() throws Exception { + Directory dir = newDirectory(); + IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, null)); + + Document doc = new Document(); + doc.add(newStringField("foo", "bar", Field.Store.NO)); + iw.addDocument(doc); + + doc = new Document(); + doc.add(newStringField("foo", "baz", Field.Store.NO)); + iw.addDocument(doc); + + DirectoryReader r1 = DirectoryReader.open(iw, true); + + iw.deleteDocuments(new Term("foo", "baz")); + DirectoryReader r2 = DirectoryReader.open(iw, true); + + FieldCache.DEFAULT.getDocTermOrds(getOnlySegmentReader(r2), "foo"); + + SortedSetDocValues v = FieldCache.DEFAULT.getDocTermOrds(getOnlySegmentReader(r1), "foo"); + assertEquals(2, v.getValueCount()); + v.setDocument(1); + assertEquals(1, v.nextOrd()); + + iw.close(); + r1.close(); + r2.close(); + dir.close(); + } } Index: lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java =================================================================== --- lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java (revision 1448313) +++ lucene/core/src/test/org/apache/lucene/search/TestFieldCache.java (working copy) @@ -472,7 +472,7 @@ } catch (IllegalStateException expected) {} try { - new DocTermOrds(ar, "binary"); + new DocTermOrds(ar, null, "binary"); fail(); } catch (IllegalStateException expected) {} @@ -486,7 +486,7 @@ } catch (IllegalStateException expected) {} try { - new DocTermOrds(ar, "sorted"); + new DocTermOrds(ar, null, "sorted"); fail(); } catch (IllegalStateException expected) {} @@ -529,7 +529,7 @@ } catch (IllegalStateException expected) {} try { - new DocTermOrds(ar, "numeric"); + new DocTermOrds(ar, null, "numeric"); fail(); } catch (IllegalStateException expected) {} @@ -554,7 +554,7 @@ } catch (IllegalStateException expected) {} try { - new DocTermOrds(ar, "sortedset"); + new DocTermOrds(ar, null, "sortedset"); fail(); } catch (IllegalStateException expected) {} Index: solr/core/src/java/org/apache/solr/request/UnInvertedField.java =================================================================== --- solr/core/src/java/org/apache/solr/request/UnInvertedField.java (revision 1448313) +++ solr/core/src/java/org/apache/solr/request/UnInvertedField.java (working copy) @@ -23,6 +23,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import org.apache.lucene.index.AtomicReader; import org.apache.lucene.index.DocTermOrds; import org.apache.lucene.index.SortedDocValues; import org.apache.lucene.index.Term; @@ -174,7 +175,8 @@ final String prefix = TrieField.getMainValuePrefix(searcher.getSchema().getFieldType(field)); this.searcher = searcher; try { - uninvert(searcher.getAtomicReader(), prefix == null ? null : new BytesRef(prefix)); + AtomicReader r = searcher.getAtomicReader(); + uninvert(r, r.getLiveDocs(), prefix == null ? null : new BytesRef(prefix)); } catch (IllegalStateException ise) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, ise.getMessage()); }