mirror of https://github.com/apache/lucene.git
LUCENE-4790: FieldCache.getDocTermOrds back to the future bug
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1448368 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4650d3aba4
commit
1ab4c5bc36
|
@ -238,6 +238,10 @@ Bug Fixes
|
||||||
is enhanced to roll up beyond the bottom cell level. (David Smiley,
|
is enhanced to roll up beyond the bottom cell level. (David Smiley,
|
||||||
Florian Schilling)
|
Florian Schilling)
|
||||||
|
|
||||||
|
* LUCENE-4790: Fix FieldCacheImpl.getDocTermOrds to not bake deletes into the
|
||||||
|
cached datastructure. Otherwise this can cause inconsistencies with readers
|
||||||
|
at different points in time. (Robert Muir)
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|
||||||
* LUCENE-4718: Fixed documentation of oal.queryparser.classic.
|
* LUCENE-4718: Fixed documentation of oal.queryparser.classic.
|
||||||
|
|
|
@ -173,30 +173,29 @@ public class DocTermOrds {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inverts all terms */
|
/** Inverts all terms */
|
||||||
public DocTermOrds(AtomicReader reader, String field) throws IOException {
|
public DocTermOrds(AtomicReader reader, Bits liveDocs, String field) throws IOException {
|
||||||
this(reader, field, null, Integer.MAX_VALUE);
|
this(reader, liveDocs, field, null, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inverts only terms starting w/ prefix */
|
/** Inverts only terms starting w/ prefix */
|
||||||
public DocTermOrds(AtomicReader reader, String field, BytesRef termPrefix) throws IOException {
|
public DocTermOrds(AtomicReader reader, Bits liveDocs, String field, BytesRef termPrefix) throws IOException {
|
||||||
this(reader, field, termPrefix, Integer.MAX_VALUE);
|
this(reader, liveDocs, field, termPrefix, Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inverts only terms starting w/ prefix, and only terms
|
/** Inverts only terms starting w/ prefix, and only terms
|
||||||
* whose docFreq (not taking deletions into account) is
|
* whose docFreq (not taking deletions into account) is
|
||||||
* <= maxTermDocFreq */
|
* <= maxTermDocFreq */
|
||||||
public DocTermOrds(AtomicReader reader, String field, BytesRef termPrefix, int maxTermDocFreq) throws IOException {
|
public DocTermOrds(AtomicReader reader, Bits liveDocs, String field, BytesRef termPrefix, int maxTermDocFreq) throws IOException {
|
||||||
this(reader, field, termPrefix, maxTermDocFreq, DEFAULT_INDEX_INTERVAL_BITS);
|
this(reader, liveDocs, field, termPrefix, maxTermDocFreq, DEFAULT_INDEX_INTERVAL_BITS);
|
||||||
uninvert(reader, termPrefix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inverts only terms starting w/ prefix, and only terms
|
/** Inverts only terms starting w/ prefix, and only terms
|
||||||
* whose docFreq (not taking deletions into account) is
|
* whose docFreq (not taking deletions into account) is
|
||||||
* <= maxTermDocFreq, with a custom indexing interval
|
* <= maxTermDocFreq, with a custom indexing interval
|
||||||
* (default is every 128nd term). */
|
* (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);
|
this(field, maxTermDocFreq, indexIntervalBits);
|
||||||
uninvert(reader, termPrefix);
|
uninvert(reader, liveDocs, termPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Subclass inits w/ this, but be sure you then call
|
/** Subclass inits w/ this, but be sure you then call
|
||||||
|
@ -257,14 +256,14 @@ public class DocTermOrds {
|
||||||
protected void visitTerm(TermsEnum te, int termNum) throws IOException {
|
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
|
* to record the document frequency for each uninverted
|
||||||
* term. */
|
* term. */
|
||||||
protected void setActualDocFreq(int termNum, int df) throws IOException {
|
protected void setActualDocFreq(int termNum, int df) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call this only once (if you subclass!) */
|
/** 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);
|
final FieldInfo info = reader.getFieldInfos().fieldInfo(field);
|
||||||
if (info != null && info.hasDocValues()) {
|
if (info != null && info.hasDocValues()) {
|
||||||
throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType());
|
throw new IllegalStateException("Type mismatch: " + field + " was indexed as " + info.getDocValuesType());
|
||||||
|
@ -304,8 +303,6 @@ public class DocTermOrds {
|
||||||
|
|
||||||
boolean testedOrd = false;
|
boolean testedOrd = false;
|
||||||
|
|
||||||
final Bits liveDocs = reader.getLiveDocs();
|
|
||||||
|
|
||||||
// we need a minimum of 9 bytes, but round up to 12 since the space would
|
// we need a minimum of 9 bytes, but round up to 12 since the space would
|
||||||
// be wasted with most allocators anyway.
|
// be wasted with most allocators anyway.
|
||||||
byte[] tempArr = new byte[12];
|
byte[] tempArr = new byte[12];
|
||||||
|
|
|
@ -1399,7 +1399,7 @@ class FieldCacheImpl implements FieldCache {
|
||||||
@Override
|
@Override
|
||||||
protected Object createValue(AtomicReader reader, CacheKey key, boolean setDocsWithField /* ignored */)
|
protected Object createValue(AtomicReader reader, CacheKey key, boolean setDocsWithField /* ignored */)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return new DocTermOrds(reader, key.field);
|
return new DocTermOrds(reader, null, key.field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class TestDocTermOrds extends LuceneTestCase {
|
||||||
w.close();
|
w.close();
|
||||||
|
|
||||||
final AtomicReader ar = SlowCompositeReaderWrapper.wrap(r);
|
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));
|
SortedSetDocValues iter = dto.iterator(ar.terms("field").iterator(null));
|
||||||
|
|
||||||
iter.setDocument(0);
|
iter.setDocument(0);
|
||||||
|
@ -295,7 +295,7 @@ public class TestDocTermOrds extends LuceneTestCase {
|
||||||
|
|
||||||
private void verify(AtomicReader r, int[][] idToOrds, BytesRef[] termsArray, BytesRef prefixRef) throws Exception {
|
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",
|
"field",
|
||||||
prefixRef,
|
prefixRef,
|
||||||
Integer.MAX_VALUE,
|
Integer.MAX_VALUE,
|
||||||
|
@ -372,4 +372,34 @@ public class TestDocTermOrds extends LuceneTestCase {
|
||||||
assertEquals(answers.length, upto);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -472,7 +472,7 @@ public class TestFieldCache extends LuceneTestCase {
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new DocTermOrds(ar, "binary");
|
new DocTermOrds(ar, null, "binary");
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ public class TestFieldCache extends LuceneTestCase {
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new DocTermOrds(ar, "sorted");
|
new DocTermOrds(ar, null, "sorted");
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ public class TestFieldCache extends LuceneTestCase {
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new DocTermOrds(ar, "numeric");
|
new DocTermOrds(ar, null, "numeric");
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ public class TestFieldCache extends LuceneTestCase {
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new DocTermOrds(ar, "sortedset");
|
new DocTermOrds(ar, null, "sortedset");
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException expected) {}
|
} catch (IllegalStateException expected) {}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.AtomicReader;
|
||||||
import org.apache.lucene.index.DocTermOrds;
|
import org.apache.lucene.index.DocTermOrds;
|
||||||
import org.apache.lucene.index.SortedDocValues;
|
import org.apache.lucene.index.SortedDocValues;
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
@ -174,7 +175,8 @@ public class UnInvertedField extends DocTermOrds {
|
||||||
final String prefix = TrieField.getMainValuePrefix(searcher.getSchema().getFieldType(field));
|
final String prefix = TrieField.getMainValuePrefix(searcher.getSchema().getFieldType(field));
|
||||||
this.searcher = searcher;
|
this.searcher = searcher;
|
||||||
try {
|
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) {
|
} catch (IllegalStateException ise) {
|
||||||
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, ise.getMessage());
|
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, ise.getMessage());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue