Skip to content

Commit 1d0a210

Browse files
committed
pass down docids in order to determine whether to load sequential
1 parent 161a429 commit 1d0a210

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

server/src/main/java/org/elasticsearch/index/engine/LuceneSyntheticSourceChangesSnapshot.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
package org.elasticsearch.index.engine;
1111

12+
import com.carrotsearch.hppc.IntArrayList;
13+
1214
import org.apache.lucene.index.LeafReaderContext;
1315
import org.apache.lucene.search.FieldDoc;
1416
import org.apache.lucene.search.ScoreDoc;
@@ -84,14 +86,7 @@ public LuceneSyntheticSourceChangesSnapshot(
8486
this.sourceLoader = mapperService.mappingLookup().newSourceLoader(null, SourceFieldMetrics.NOOP);
8587
Set<String> storedFields = sourceLoader.requiredStoredFields();
8688

87-
// If more than a few ops are requested let's enforce a sequential reader. Typically, thousands of ops may be requested.
88-
// Given how LuceneSyntheticSourceChangesSnapshot accesses stored field, it should always benefit from using sequential reader.
89-
//
90-
// A sequential reader decompresses a block eagerly, so that increasing adjacent doc ids can access stored fields without
91-
// compressing on each StoredFields#document(docId) invocation. The only downside is the last few operations in the request
92-
// seq_no range are at the beginning of a block, which means stored fields for many docs are being decompressed that isn't used.
93-
boolean shouldForceSequentialReader = toSeqNo - fromSeqNo > 10;
94-
this.storedFieldLoader = StoredFieldLoader.create(false, storedFields, shouldForceSequentialReader);
89+
this.storedFieldLoader = StoredFieldLoader.createLoaderWithMaybeSequentialReader(storedFields);
9590
this.lastSeenSeqNo = fromSeqNo - 1;
9691
}
9792

@@ -199,8 +194,19 @@ private Translog.Operation[] loadDocuments(List<SearchRecord> documentRecords) t
199194
maxDoc = leafReaderContext.reader().maxDoc();
200195
} while (docRecord.docID() >= docBase + maxDoc);
201196

202-
leafFieldLoader = storedFieldLoader.getLoader(leafReaderContext, null);
203-
leafSourceLoader = sourceLoader.leaf(leafReaderContext.reader(), null);
197+
IntArrayList nextDocIds = new IntArrayList();
198+
for (int j = i; j < documentRecords.size(); j++) {
199+
int docID = documentRecords.get(j).docID();
200+
if (docBase + maxDoc >= docID) {
201+
break;
202+
}
203+
int segmentDocID = docID - docBase;
204+
nextDocIds.add(segmentDocID);
205+
}
206+
207+
int[] nextDocIdArray = nextDocIds.toArray();
208+
leafFieldLoader = storedFieldLoader.getLoader(leafReaderContext, nextDocIdArray);
209+
leafSourceLoader = sourceLoader.leaf(leafReaderContext.reader(), nextDocIdArray);
204210
setNextSourceMetadataReader(leafReaderContext);
205211
}
206212
int segmentDocID = docRecord.docID() - docBase;

server/src/main/java/org/elasticsearch/index/fieldvisitor/StoredFieldLoader.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,35 @@ public Map<String, List<Object>> storedFields() {
235235
}
236236
}
237237

238+
public static StoredFieldLoader createLoaderWithMaybeSequentialReader(Set<String> fields) {
239+
List<String> fieldsToLoad = fieldsToLoad(false, fields);
240+
return new StoredFieldLoader() {
241+
@Override
242+
public LeafStoredFieldLoader getLoader(LeafReaderContext ctx, int[] docs) throws IOException {
243+
return new ReaderStoredFieldLoader(maybeSequentialReaderWithSmallDocIdGaps(ctx, docs), false, fields);
244+
}
245+
246+
@Override
247+
public List<String> fieldsToLoad() {
248+
return fieldsToLoad;
249+
}
250+
};
251+
}
252+
253+
private static CheckedBiConsumer<Integer, FieldsVisitor, IOException> maybeSequentialReaderWithSmallDocIdGaps(
254+
LeafReaderContext ctx,
255+
int[] docs
256+
) throws IOException {
257+
LeafReader leafReader = ctx.reader();
258+
if (docs != null && docs.length > 10 && hasNearSequentialDocs(docs)) {
259+
return sequentialReader(ctx);
260+
}
261+
StoredFields storedFields = leafReader.storedFields();
262+
return storedFields::document;
263+
}
264+
265+
private static boolean hasNearSequentialDocs(int[] docs) {
266+
return docs.length > 0 && docs[docs.length - 1] - docs[0] <= (1.2 * docs.length - 1);
267+
}
268+
238269
}

0 commit comments

Comments
 (0)