From 693be344cbc991b587505afd8f6a09ee03bf490d Mon Sep 17 00:00:00 2001 From: Christophe Bismuth Date: Thu, 15 Nov 2018 10:18:32 +0100 Subject: [PATCH] LUCENE-8552: Optimize getMergedFieldInfos for one-segment FieldInfos --- .../org/apache/lucene/index/FieldInfos.java | 23 ++++++---- .../apache/lucene/index/TestFieldInfos.java | 46 +++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java b/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java index 5cd9639725f4..88f092a9d1be 100644 --- a/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java +++ b/lucene/core/src/java/org/apache/lucene/index/FieldInfos.java @@ -139,15 +139,22 @@ public FieldInfos(FieldInfo[] infos) { * will be unavailable. */ public static FieldInfos getMergedFieldInfos(IndexReader reader) { - final String softDeletesField = reader.leaves().stream() - .map(l -> l.reader().getFieldInfos().getSoftDeletesField()) - .filter(Objects::nonNull) - .findAny().orElse(null); - final Builder builder = new Builder(new FieldNumbers(softDeletesField)); - for(final LeafReaderContext ctx : reader.leaves()) { - builder.add(ctx.reader().getFieldInfos()); + final List leaves = reader.leaves(); + if (leaves.isEmpty()) { + return FieldInfos.EMPTY; + } else if (leaves.size() == 1) { + return leaves.get(0).reader().getFieldInfos(); + } else { + final String softDeletesField = leaves.stream() + .map(l -> l.reader().getFieldInfos().getSoftDeletesField()) + .filter(Objects::nonNull) + .findAny().orElse(null); + final Builder builder = new Builder(new FieldNumbers(softDeletesField)); + for (final LeafReaderContext ctx : leaves) { + builder.add(ctx.reader().getFieldInfos()); + } + return builder.finish(); } - return builder.finish(); } /** Returns a set of names of fields that have a terms index. The order is undefined. */ diff --git a/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java b/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java index 308e11ebe969..3fe5fa9d2c3f 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestFieldInfos.java @@ -17,6 +17,7 @@ package org.apache.lucene.index; +import java.io.IOException; import java.util.Iterator; import org.apache.lucene.analysis.MockAnalyzer; @@ -26,6 +27,9 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.sameInstance; + public class TestFieldInfos extends LuceneTestCase { public void testFieldInfos() throws Exception{ @@ -89,4 +93,46 @@ public void testFieldInfos() throws Exception{ dir.close(); } + public void testMergedFieldInfos_empty() throws IOException { + Directory dir = newDirectory(); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))); + + IndexReader reader = writer.getReader(); + FieldInfos actual = FieldInfos.getMergedFieldInfos(reader); + FieldInfos expected = FieldInfos.EMPTY; + + assertThat(actual, sameInstance(expected)); + + reader.close(); + writer.close(); + dir.close(); + } + + public void testMergedFieldInfos_singleLeaf() throws IOException { + Directory dir = newDirectory(); + IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(new MockAnalyzer(random()))); + + Document d1 = new Document(); + d1.add(new StringField("f1", "v1", Field.Store.YES)); + writer.addDocument(d1); + writer.commit(); + + Document d2 = new Document(); + d2.add(new StringField("f2", "v2", Field.Store.YES)); + writer.addDocument(d2); + writer.commit(); + + writer.forceMerge(1); + + IndexReader reader = writer.getReader(); + FieldInfos actual = FieldInfos.getMergedFieldInfos(reader); + FieldInfos expected = reader.leaves().get(0).reader().getFieldInfos(); + + assertThat(reader.leaves().size(), equalTo(1)); + assertThat(actual, sameInstance(expected)); + + reader.close(); + writer.close(); + dir.close(); + } }