Skip to content

Commit 1b90c46

Browse files
committed
Allow reader wrappers to have different live docs but the same cache key.
Relates to #19856
1 parent 0036f28 commit 1b90c46

File tree

3 files changed

+32
-32
lines changed

3 files changed

+32
-32
lines changed

core/src/main/java/org/elasticsearch/common/lucene/uid/PerThreadIDVersionAndSeqNoLookup.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,6 @@ final class PerThreadIDVersionAndSeqNoLookup {
5252
// TODO: do we really need to store all this stuff? some if it might not speed up anything.
5353
// we keep it around for now, to reduce the amount of e.g. hash lookups by field and stuff
5454

55-
/** The {@link LeafReaderContext} that needs to be looked up. */
56-
private final LeafReaderContext context;
57-
/** Live docs of the context, cached to avoid the cost of ensureOpen() on every
58-
* segment for every index operation. */
59-
private final Bits liveDocs;
60-
6155
/** terms enum for uid field */
6256
final String uidField;
6357
private final TermsEnum termsEnum;
@@ -71,10 +65,7 @@ final class PerThreadIDVersionAndSeqNoLookup {
7165
/**
7266
* Initialize lookup for the provided segment
7367
*/
74-
PerThreadIDVersionAndSeqNoLookup(LeafReaderContext context, String uidField) throws IOException {
75-
this.context = context;
76-
final LeafReader reader = context.reader();
77-
this.liveDocs = reader.getLiveDocs();
68+
PerThreadIDVersionAndSeqNoLookup(LeafReader reader, String uidField) throws IOException {
7869
this.uidField = uidField;
7970
Fields fields = reader.fields();
8071
Terms terms = fields.terms(uidField);
@@ -91,12 +82,17 @@ final class PerThreadIDVersionAndSeqNoLookup {
9182
this.readerKey = readerKey;
9283
}
9384

94-
/** Return null if id is not found. */
95-
public DocIdAndVersion lookupVersion(BytesRef id)
85+
/** Return null if id is not found.
86+
* We pass the {@link LeafReaderContext} as an argument so that things
87+
* still work with reader wrappers that hide some documents while still
88+
* using the same cache key. Otherwise we'd have to disable caching
89+
* entirely for these readers.
90+
*/
91+
public DocIdAndVersion lookupVersion(BytesRef id, LeafReaderContext context)
9692
throws IOException {
9793
assert context.reader().getCoreCacheHelper().getKey().equals(readerKey) :
9894
"context's reader is not the same as the reader class was initialized on.";
99-
int docID = getDocID(id);
95+
int docID = getDocID(id, context.reader().getLiveDocs());
10096

10197
if (docID != DocIdSetIterator.NO_MORE_DOCS) {
10298
final NumericDocValues versions = context.reader().getNumericDocValues(VersionFieldMapper.NAME);
@@ -116,7 +112,7 @@ public DocIdAndVersion lookupVersion(BytesRef id)
116112
* returns the internal lucene doc id for the given id bytes.
117113
* {@link DocIdSetIterator#NO_MORE_DOCS} is returned if not found
118114
* */
119-
private int getDocID(BytesRef id) throws IOException {
115+
private int getDocID(BytesRef id, Bits liveDocs) throws IOException {
120116
if (termsEnum.seekExact(id)) {
121117
int docID = DocIdSetIterator.NO_MORE_DOCS;
122118
// there may be more than one matching docID, in the case of nested docs, so we want the last one:
@@ -134,8 +130,10 @@ private int getDocID(BytesRef id) throws IOException {
134130
}
135131

136132
/** Return null if id is not found. */
137-
DocIdAndSeqNo lookupSeqNo(BytesRef id) throws IOException {
138-
int docID = getDocID(id);
133+
DocIdAndSeqNo lookupSeqNo(BytesRef id, LeafReaderContext context) throws IOException {
134+
assert context.reader().getCoreCacheHelper().getKey().equals(readerKey) :
135+
"context's reader is not the same as the reader class was initialized on.";
136+
int docID = getDocID(id, context.reader().getLiveDocs());
139137
if (docID != DocIdSetIterator.NO_MORE_DOCS) {
140138
NumericDocValues seqNos = context.reader().getNumericDocValues(SeqNoFieldMapper.NAME);
141139
long seqNo;

core/src/main/java/org/elasticsearch/common/lucene/uid/VersionsAndSeqNoResolver.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private static PerThreadIDVersionAndSeqNoLookup[] getLookupState(IndexReader rea
7373
if (lookupState == null) {
7474
lookupState = new PerThreadIDVersionAndSeqNoLookup[reader.leaves().size()];
7575
for (LeafReaderContext leaf : reader.leaves()) {
76-
lookupState[leaf.ord] = new PerThreadIDVersionAndSeqNoLookup(leaf, uidField);
76+
lookupState[leaf.ord] = new PerThreadIDVersionAndSeqNoLookup(leaf.reader(), uidField);
7777
}
7878
ctl.set(lookupState);
7979
}
@@ -132,8 +132,9 @@ public static DocIdAndVersion loadDocIdAndVersion(IndexReader reader, Term term)
132132
// iterate backwards to optimize for the frequently updated documents
133133
// which are likely to be in the last segments
134134
for (int i = leaves.size() - 1; i >= 0; i--) {
135-
PerThreadIDVersionAndSeqNoLookup lookup = lookups[leaves.get(i).ord];
136-
DocIdAndVersion result = lookup.lookupVersion(term.bytes());
135+
final LeafReaderContext leaf = leaves.get(i);
136+
PerThreadIDVersionAndSeqNoLookup lookup = lookups[leaf.ord];
137+
DocIdAndVersion result = lookup.lookupVersion(term.bytes(), leaf);
137138
if (result != null) {
138139
return result;
139140
}
@@ -153,8 +154,9 @@ public static DocIdAndSeqNo loadDocIdAndSeqNo(IndexReader reader, Term term) thr
153154
// iterate backwards to optimize for the frequently updated documents
154155
// which are likely to be in the last segments
155156
for (int i = leaves.size() - 1; i >= 0; i--) {
156-
PerThreadIDVersionAndSeqNoLookup lookup = lookups[leaves.get(i).ord];
157-
DocIdAndSeqNo result = lookup.lookupSeqNo(term.bytes());
157+
final LeafReaderContext leaf = leaves.get(i);
158+
PerThreadIDVersionAndSeqNoLookup lookup = lookups[leaf.ord];
159+
DocIdAndSeqNo result = lookup.lookupSeqNo(term.bytes(), leaf);
158160
if (result != null) {
159161
return result;
160162
}

core/src/test/java/org/elasticsearch/common/lucene/uid/VersionLookupTests.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,21 @@ public void testSimple() throws Exception {
5656
writer.addDocument(new Document());
5757
DirectoryReader reader = DirectoryReader.open(writer);
5858
LeafReaderContext segment = reader.leaves().get(0);
59-
PerThreadIDVersionAndSeqNoLookup lookup = new PerThreadIDVersionAndSeqNoLookup(segment, IdFieldMapper.NAME);
59+
PerThreadIDVersionAndSeqNoLookup lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME);
6060
// found doc
61-
DocIdAndVersion result = lookup.lookupVersion(new BytesRef("6"));
61+
DocIdAndVersion result = lookup.lookupVersion(new BytesRef("6"), segment);
6262
assertNotNull(result);
6363
assertEquals(87, result.version);
6464
assertEquals(0, result.docId);
6565
// not found doc
66-
assertNull(lookup.lookupVersion(new BytesRef("7")));
66+
assertNull(lookup.lookupVersion(new BytesRef("7"), segment));
6767
// deleted doc
6868
writer.deleteDocuments(new Term(IdFieldMapper.NAME, "6"));
6969
reader.close();
7070
reader = DirectoryReader.open(writer);
7171
segment = reader.leaves().get(0);
72-
lookup = new PerThreadIDVersionAndSeqNoLookup(segment, IdFieldMapper.NAME);
73-
assertNull(lookup.lookupVersion(new BytesRef("6")));
72+
lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME);
73+
assertNull(lookup.lookupVersion(new BytesRef("6"), segment));
7474
reader.close();
7575
writer.close();
7676
dir.close();
@@ -91,9 +91,9 @@ public void testTwoDocuments() throws Exception {
9191
writer.addDocument(new Document());
9292
DirectoryReader reader = DirectoryReader.open(writer);
9393
LeafReaderContext segment = reader.leaves().get(0);
94-
PerThreadIDVersionAndSeqNoLookup lookup = new PerThreadIDVersionAndSeqNoLookup(segment, IdFieldMapper.NAME);
94+
PerThreadIDVersionAndSeqNoLookup lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME);
9595
// return the last doc when there are duplicates
96-
DocIdAndVersion result = lookup.lookupVersion(new BytesRef("6"));
96+
DocIdAndVersion result = lookup.lookupVersion(new BytesRef("6"), segment);
9797
assertNotNull(result);
9898
assertEquals(87, result.version);
9999
assertEquals(1, result.docId);
@@ -102,8 +102,8 @@ public void testTwoDocuments() throws Exception {
102102
reader.close();
103103
reader = DirectoryReader.open(writer);
104104
segment = reader.leaves().get(0);
105-
lookup = new PerThreadIDVersionAndSeqNoLookup(segment, IdFieldMapper.NAME);
106-
result = lookup.lookupVersion(new BytesRef("6"));
105+
lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME);
106+
result = lookup.lookupVersion(new BytesRef("6"), segment);
107107
assertNotNull(result);
108108
assertEquals(87, result.version);
109109
assertEquals(1, result.docId);
@@ -112,8 +112,8 @@ public void testTwoDocuments() throws Exception {
112112
reader.close();
113113
reader = DirectoryReader.open(writer);
114114
segment = reader.leaves().get(0);
115-
lookup = new PerThreadIDVersionAndSeqNoLookup(segment, IdFieldMapper.NAME);
116-
assertNull(lookup.lookupVersion(new BytesRef("6")));
115+
lookup = new PerThreadIDVersionAndSeqNoLookup(segment.reader(), IdFieldMapper.NAME);
116+
assertNull(lookup.lookupVersion(new BytesRef("6"), segment));
117117
reader.close();
118118
writer.close();
119119
dir.close();

0 commit comments

Comments
 (0)