diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 54329abe7cd..6defb272b47 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -25,6 +25,8 @@ API Changes * LUCENE-7475: Norms now support sparsity, allowing to pay for what is actually used. (Adrien Grand) +* LUCENE-7494: Points now have a per-field API, like doc values. (Adrien Grand) + Bug Fixes Improvements diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDReader.java index 35e94489472..a2b784afd27 100644 --- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDReader.java +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDReader.java @@ -20,7 +20,6 @@ package org.apache.lucene.codecs.simpletext; import java.io.IOException; import java.nio.charset.StandardCharsets; -import org.apache.lucene.index.PointValues.IntersectVisitor; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsReader.java index 1477f17fa0b..e3b880afb4e 100644 --- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsReader.java +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsReader.java @@ -26,6 +26,7 @@ import org.apache.lucene.codecs.PointsReader; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; +import org.apache.lucene.index.PointValues; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.store.BufferedChecksumIndexInput; import org.apache.lucene.store.ChecksumIndexInput; @@ -174,7 +175,8 @@ class SimpleTextPointsReader extends PointsReader { return new String(scratch.bytes(), prefix.length, scratch.length() - prefix.length, StandardCharsets.UTF_8); } - private BKDReader getBKDReader(String fieldName) { + @Override + public PointValues getValues(String fieldName) throws IOException { FieldInfo fieldInfo = readState.fieldInfos.fieldInfo(fieldName); if (fieldInfo == null) { throw new IllegalArgumentException("field=\"" + fieldName + "\" is unrecognized"); @@ -185,18 +187,6 @@ class SimpleTextPointsReader extends PointsReader { return readers.get(fieldName); } - /** Finds all documents and points matching the provided visitor */ - @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return; - } - bkdReader.intersect(visitor); - } - @Override public void checkIntegrity() throws IOException { BytesRefBuilder scratch = new BytesRefBuilder(); @@ -234,69 +224,4 @@ class SimpleTextPointsReader extends PointsReader { return "SimpleTextPointsReader(segment=" + readState.segmentInfo.name + " maxDoc=" + readState.segmentInfo.maxDoc() + ")"; } - @Override - public byte[] getMinPackedValue(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return null; - } - return bkdReader.getMinPackedValue(); - } - - @Override - public byte[] getMaxPackedValue(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return null; - } - return bkdReader.getMaxPackedValue(); - } - - @Override - public int getNumDimensions(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return 0; - } - return bkdReader.getNumDimensions(); - } - - @Override - public int getBytesPerDimension(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return 0; - } - return bkdReader.getBytesPerDimension(); - } - - @Override - public long size(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return 0; - } - return bkdReader.getPointCount(); - } - - @Override - public int getDocCount(String fieldName) { - BKDReader bkdReader = getBKDReader(fieldName); - if (bkdReader == null) { - // Schema ghost corner case! This field did index points in the past, but - // now all docs having this field were deleted in this segment: - return 0; - } - return bkdReader.getDocCount(); - } } diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsWriter.java index 8d5c0344509..c06c128d154 100644 --- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsWriter.java +++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextPointsWriter.java @@ -26,6 +26,7 @@ import org.apache.lucene.codecs.PointsReader; import org.apache.lucene.codecs.PointsWriter; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; +import org.apache.lucene.index.PointValues; import org.apache.lucene.index.PointValues.IntersectVisitor; import org.apache.lucene.index.PointValues.Relation; import org.apache.lucene.index.SegmentWriteState; @@ -68,9 +69,10 @@ class SimpleTextPointsWriter extends PointsWriter { } @Override - public void writeField(FieldInfo fieldInfo, PointsReader values) throws IOException { + public void writeField(FieldInfo fieldInfo, PointsReader reader) throws IOException { - boolean singleValuePerDoc = values.size(fieldInfo.name) == values.getDocCount(fieldInfo.name); + PointValues values = reader.getValues(fieldInfo.name); + boolean singleValuePerDoc = values.size() == values.getDocCount(); // We use the normal BKDWriter, but subclass to customize how it writes the index and blocks to disk: try (BKDWriter writer = new BKDWriter(writeState.segmentInfo.maxDoc(), @@ -80,7 +82,7 @@ class SimpleTextPointsWriter extends PointsWriter { fieldInfo.getPointNumBytes(), BKDWriter.DEFAULT_MAX_POINTS_IN_LEAF_NODE, BKDWriter.DEFAULT_MAX_MB_SORT_IN_HEAP, - values.size(fieldInfo.name), + values.size(), singleValuePerDoc) { @Override @@ -173,7 +175,7 @@ class SimpleTextPointsWriter extends PointsWriter { } }) { - values.intersect(fieldInfo.name, new IntersectVisitor() { + values.intersect(new IntersectVisitor() { @Override public void visit(int docID) { throw new IllegalStateException(); diff --git a/lucene/core/src/java/org/apache/lucene/codecs/MutablePointsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/MutablePointValues.java similarity index 87% rename from lucene/core/src/java/org/apache/lucene/codecs/MutablePointsReader.java rename to lucene/core/src/java/org/apache/lucene/codecs/MutablePointValues.java index dccca26e012..8f4d69c4549 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/MutablePointsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/MutablePointValues.java @@ -16,15 +16,16 @@ */ package org.apache.lucene.codecs; +import org.apache.lucene.index.PointValues; import org.apache.lucene.util.BytesRef; -/** {@link PointsReader} whose order of points can be changed. +/** {@link PointValues} whose order of points can be changed. * This class is useful for codecs to optimize flush. * @lucene.internal */ -public abstract class MutablePointsReader extends PointsReader { +public abstract class MutablePointValues extends PointValues { /** Sole constructor. */ - protected MutablePointsReader() {} + protected MutablePointValues() {} /** Set {@code packedValue} with a reference to the packed bytes of the i-th value. */ public abstract void getValue(int i, BytesRef packedValue); diff --git a/lucene/core/src/java/org/apache/lucene/codecs/PointsFormat.java b/lucene/core/src/java/org/apache/lucene/codecs/PointsFormat.java index e49bf53afc6..1723e42c05b 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/PointsFormat.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/PointsFormat.java @@ -19,6 +19,7 @@ package org.apache.lucene.codecs; import java.io.IOException; +import org.apache.lucene.index.PointValues; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.SegmentWriteState; @@ -72,38 +73,8 @@ public abstract class PointsFormat { } @Override - public void intersect(String fieldName, IntersectVisitor visitor) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public byte[] getMinPackedValue(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public byte[] getMaxPackedValue(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public int getNumDimensions(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public int getBytesPerDimension(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public long size(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); - } - - @Override - public int getDocCount(String fieldName) { - throw new IllegalArgumentException("field=\"" + fieldName + "\" was not indexed with points"); + public PointValues getValues(String field) { + throw new IllegalArgumentException("field=\"" + field + "\" was not indexed with points"); } }; } diff --git a/lucene/core/src/java/org/apache/lucene/codecs/PointsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/PointsReader.java index ab21431cd6f..b20614afc72 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/PointsReader.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/PointsReader.java @@ -27,7 +27,7 @@ import org.apache.lucene.util.Accountable; * * @lucene.experimental */ -public abstract class PointsReader extends PointValues implements Closeable, Accountable { +public abstract class PointsReader implements Closeable, Accountable { /** Sole constructor. (For invocation by subclass constructors, typically implicit.) */ protected PointsReader() {} @@ -41,6 +41,9 @@ public abstract class PointsReader extends PointValues implements Closeable, Acc */ public abstract void checkIntegrity() throws IOException; + /** Return {@link PointValues} for the given {@code field}. */ + public abstract PointValues getValues(String field) throws IOException; + /** * Returns an instance optimized for merging. *

diff --git a/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java b/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java index eac171649bc..38cd440e68c 100644 --- a/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java +++ b/lucene/core/src/java/org/apache/lucene/codecs/PointsWriter.java @@ -22,6 +22,7 @@ import java.io.IOException; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.MergeState; +import org.apache.lucene.index.PointValues; /** Abstract API to write points * @@ -48,109 +49,121 @@ public abstract class PointsWriter implements Closeable { if (pointsReader != null) { FieldInfo readerFieldInfo = mergeState.fieldInfos[i].fieldInfo(fieldInfo.name); if (readerFieldInfo != null && readerFieldInfo.getPointDimensionCount() > 0) { - maxPointCount += pointsReader.size(fieldInfo.name); - docCount += pointsReader.getDocCount(fieldInfo.name); + PointValues values = pointsReader.getValues(fieldInfo.name); + if (values != null) { + maxPointCount += values.size(); + docCount += values.getDocCount(); + } } } } final long finalMaxPointCount = maxPointCount; final int finalDocCount = docCount; writeField(fieldInfo, - new PointsReader() { - @Override - public void intersect(String fieldName, IntersectVisitor mergedVisitor) throws IOException { - if (fieldName.equals(fieldInfo.name) == false) { - throw new IllegalArgumentException("field name must match the field being merged"); - } - - for (int i=0;i 0) { - totMaxSize += reader.size(fieldInfo.name); - singleValuePerDoc &= reader.size(fieldInfo.name) == reader.getDocCount(fieldInfo.name); + PointValues values = reader.getValues(fieldInfo.name); + if (values != null) { + totMaxSize += values.size(); + singleValuePerDoc &= values.size() == values.getDocCount(); + } } } } diff --git a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java index 27d7c50cc25..aec75375d7b 100644 --- a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java +++ b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java @@ -1793,8 +1793,8 @@ public final class CheckIndex implements Closeable { try { if (fieldInfos.hasPointValues()) { - PointsReader values = reader.getPointsReader(); - if (values == null) { + PointsReader pointsReader = reader.getPointsReader(); + if (pointsReader == null) { throw new RuntimeException("there are fields with points, but reader.getPointsReader() is null"); } for (FieldInfo fieldInfo : fieldInfos) { @@ -1812,9 +1812,13 @@ public final class CheckIndex implements Closeable { long[] pointCountSeen = new long[1]; - byte[] globalMinPackedValue = values.getMinPackedValue(fieldInfo.name); - long size = values.size(fieldInfo.name); - int docCount = values.getDocCount(fieldInfo.name); + PointValues values = pointsReader.getValues(fieldInfo.name); + if (values == null) { + continue; + } + byte[] globalMinPackedValue = values.getMinPackedValue(); + long size = values.size(); + int docCount = values.getDocCount(); if (docCount > size) { throw new RuntimeException("point values for field \"" + fieldInfo.name + "\" claims to have size=" + size + " points and inconsistent docCount=" + docCount); @@ -1831,7 +1835,7 @@ public final class CheckIndex implements Closeable { } else if (globalMinPackedValue.length != packedBytesCount) { throw new RuntimeException("getMinPackedValue for field \"" + fieldInfo.name + "\" return length=" + globalMinPackedValue.length + " array, but should be " + packedBytesCount); } - byte[] globalMaxPackedValue = values.getMaxPackedValue(fieldInfo.name); + byte[] globalMaxPackedValue = values.getMaxPackedValue(); if (globalMaxPackedValue == null) { if (size != 0) { throw new RuntimeException("getMaxPackedValue is null points for field \"" + fieldInfo.name + "\" yet size=" + size); @@ -1840,8 +1844,7 @@ public final class CheckIndex implements Closeable { throw new RuntimeException("getMaxPackedValue for field \"" + fieldInfo.name + "\" return length=" + globalMaxPackedValue.length + " array, but should be " + packedBytesCount); } - values.intersect(fieldInfo.name, - new PointValues.IntersectVisitor() { + values.intersect(new PointValues.IntersectVisitor() { private int lastDocID = -1; diff --git a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java index b9ad73ad3d5..460a9d6cf34 100644 --- a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java @@ -188,6 +188,18 @@ public abstract class CodecReader extends LeafReader implements Accountable { return getNormsReader().getNorms(fi); } + @Override + public final PointValues getPointValues(String field) throws IOException { + ensureOpen(); + FieldInfo fi = getFieldInfos().fieldInfo(field); + if (fi == null || fi.getPointDimensionCount() == 0) { + // Field does not exist or does not index points + return null; + } + + return getPointsReader().getValues(field); + } + @Override protected void doClose() throws IOException { } diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java index 13b6e8d6d4d..48cbda723fe 100644 --- a/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/FilterCodecReader.java @@ -87,11 +87,6 @@ public abstract class FilterCodecReader extends CodecReader { return in.getPointsReader(); } - @Override - public PointValues getPointValues() { - return in.getPointValues(); - } - @Override public int numDocs() { return in.numDocs(); diff --git a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java index 9e9fcb4821f..9ed62e70b56 100644 --- a/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/FilterLeafReader.java @@ -382,8 +382,8 @@ public abstract class FilterLeafReader extends LeafReader { } @Override - public PointValues getPointValues() { - return in.getPointValues(); + public PointValues getPointValues(String field) throws IOException { + return in.getPointValues(field); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/index/LeafReader.java b/lucene/core/src/java/org/apache/lucene/index/LeafReader.java index 1b677673f68..acdd0d87bd7 100644 --- a/lucene/core/src/java/org/apache/lucene/index/LeafReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/LeafReader.java @@ -295,8 +295,9 @@ public abstract class LeafReader extends IndexReader { public abstract Bits getLiveDocs(); /** Returns the {@link PointValues} used for numeric or - * spatial searches, or null if there are no point fields. */ - public abstract PointValues getPointValues(); + * spatial searches for the given field, or null if there + * are no point fields. */ + public abstract PointValues getPointValues(String field) throws IOException; /** * Checks consistency of this reader. diff --git a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java index 4c06b38d5e4..7eb90dff7ce 100644 --- a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java +++ b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java @@ -197,8 +197,8 @@ class MergeReaderWrapper extends LeafReader { } @Override - public PointValues getPointValues() { - return in.getPointValues(); + public PointValues getPointValues(String fieldName) throws IOException { + return in.getPointValues(fieldName); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/index/ParallelLeafReader.java b/lucene/core/src/java/org/apache/lucene/index/ParallelLeafReader.java index f4afa11f9ca..60886ea20d0 100644 --- a/lucene/core/src/java/org/apache/lucene/index/ParallelLeafReader.java +++ b/lucene/core/src/java/org/apache/lucene/index/ParallelLeafReader.java @@ -321,99 +321,10 @@ public class ParallelLeafReader extends LeafReader { } @Override - public PointValues getPointValues() { - return new PointValues() { - @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return; - } - dimValues.intersect(fieldName, visitor); - } - - @Override - public byte[] getMinPackedValue(String fieldName) throws IOException { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return null; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return null; - } - return dimValues.getMinPackedValue(fieldName); - } - - @Override - public byte[] getMaxPackedValue(String fieldName) throws IOException { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return null; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return null; - } - return dimValues.getMaxPackedValue(fieldName); - } - - @Override - public int getNumDimensions(String fieldName) throws IOException { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return 0; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return 0; - } - return dimValues.getNumDimensions(fieldName); - } - - @Override - public int getBytesPerDimension(String fieldName) throws IOException { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return 0; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return 0; - } - return dimValues.getBytesPerDimension(fieldName); - } - - @Override - public long size(String fieldName) { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return 0; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return 0; - } - return dimValues.size(fieldName); - } - - @Override - public int getDocCount(String fieldName) { - LeafReader reader = fieldToReader.get(fieldName); - if (reader == null) { - return 0; - } - PointValues dimValues = reader.getPointValues(); - if (dimValues == null) { - return 0; - } - return dimValues.getDocCount(fieldName); - } - }; + public PointValues getPointValues(String fieldName) throws IOException { + ensureOpen(); + LeafReader reader = fieldToReader.get(fieldName); + return reader == null ? null : reader.getPointValues(fieldName); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/index/PointValues.java b/lucene/core/src/java/org/apache/lucene/index/PointValues.java index 528f97184ae..ffac5f7dbd0 100644 --- a/lucene/core/src/java/org/apache/lucene/index/PointValues.java +++ b/lucene/core/src/java/org/apache/lucene/index/PointValues.java @@ -89,16 +89,14 @@ public abstract class PointValues { /** Return the cumulated number of points across all leaves of the given * {@link IndexReader}. Leaves that do not have points for the given field * are ignored. - * @see PointValues#size(String) */ + * @see PointValues#size() */ public static long size(IndexReader reader, String field) throws IOException { long size = 0; for (LeafReaderContext ctx : reader.leaves()) { - FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field); - if (info == null || info.getPointDimensionCount() == 0) { - continue; + PointValues values = ctx.reader().getPointValues(field); + if (values != null) { + size += values.size(); } - PointValues values = ctx.reader().getPointValues(); - size += values.size(field); } return size; } @@ -106,16 +104,14 @@ public abstract class PointValues { /** Return the cumulated number of docs that have points across all leaves * of the given {@link IndexReader}. Leaves that do not have points for the * given field are ignored. - * @see PointValues#getDocCount(String) */ + * @see PointValues#getDocCount() */ public static int getDocCount(IndexReader reader, String field) throws IOException { int count = 0; for (LeafReaderContext ctx : reader.leaves()) { - FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field); - if (info == null || info.getPointDimensionCount() == 0) { - continue; + PointValues values = ctx.reader().getPointValues(field); + if (values != null) { + count += values.getDocCount(); } - PointValues values = ctx.reader().getPointValues(); - count += values.getDocCount(field); } return count; } @@ -123,24 +119,23 @@ public abstract class PointValues { /** Return the minimum packed values across all leaves of the given * {@link IndexReader}. Leaves that do not have points for the given field * are ignored. - * @see PointValues#getMinPackedValue(String) */ + * @see PointValues#getMinPackedValue() */ public static byte[] getMinPackedValue(IndexReader reader, String field) throws IOException { byte[] minValue = null; for (LeafReaderContext ctx : reader.leaves()) { - FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field); - if (info == null || info.getPointDimensionCount() == 0) { + PointValues values = ctx.reader().getPointValues(field); + if (values == null) { continue; } - PointValues values = ctx.reader().getPointValues(); - byte[] leafMinValue = values.getMinPackedValue(field); + byte[] leafMinValue = values.getMinPackedValue(); if (leafMinValue == null) { continue; } if (minValue == null) { minValue = leafMinValue.clone(); } else { - final int numDimensions = values.getNumDimensions(field); - final int numBytesPerDimension = values.getBytesPerDimension(field); + final int numDimensions = values.getNumDimensions(); + final int numBytesPerDimension = values.getBytesPerDimension(); for (int i = 0; i < numDimensions; ++i) { int offset = i * numBytesPerDimension; if (StringHelper.compare(numBytesPerDimension, leafMinValue, offset, minValue, offset) < 0) { @@ -155,24 +150,23 @@ public abstract class PointValues { /** Return the maximum packed values across all leaves of the given * {@link IndexReader}. Leaves that do not have points for the given field * are ignored. - * @see PointValues#getMaxPackedValue(String) */ + * @see PointValues#getMaxPackedValue() */ public static byte[] getMaxPackedValue(IndexReader reader, String field) throws IOException { byte[] maxValue = null; for (LeafReaderContext ctx : reader.leaves()) { - FieldInfo info = ctx.reader().getFieldInfos().fieldInfo(field); - if (info == null || info.getPointDimensionCount() == 0) { + PointValues values = ctx.reader().getPointValues(field); + if (values == null) { continue; } - PointValues values = ctx.reader().getPointValues(); - byte[] leafMaxValue = values.getMaxPackedValue(field); + byte[] leafMaxValue = values.getMaxPackedValue(); if (leafMaxValue == null) { continue; } if (maxValue == null) { maxValue = leafMaxValue.clone(); } else { - final int numDimensions = values.getNumDimensions(field); - final int numBytesPerDimension = values.getBytesPerDimension(field); + final int numDimensions = values.getNumDimensions(); + final int numBytesPerDimension = values.getBytesPerDimension(); for (int i = 0; i < numDimensions; ++i) { int offset = i * numBytesPerDimension; if (StringHelper.compare(numBytesPerDimension, leafMaxValue, offset, maxValue, offset) > 0) { @@ -224,23 +218,23 @@ public abstract class PointValues { /** Finds all documents and points matching the provided visitor. * This method does not enforce live documents, so it's up to the caller * to test whether each document is deleted, if necessary. */ - public abstract void intersect(String fieldName, IntersectVisitor visitor) throws IOException; + public abstract void intersect(IntersectVisitor visitor) throws IOException; /** Returns minimum value for each dimension, packed, or null if {@link #size} is 0 */ - public abstract byte[] getMinPackedValue(String fieldName) throws IOException; + public abstract byte[] getMinPackedValue() throws IOException; /** Returns maximum value for each dimension, packed, or null if {@link #size} is 0 */ - public abstract byte[] getMaxPackedValue(String fieldName) throws IOException; + public abstract byte[] getMaxPackedValue() throws IOException; /** Returns how many dimensions were indexed */ - public abstract int getNumDimensions(String fieldName) throws IOException; + public abstract int getNumDimensions() throws IOException; /** Returns the number of bytes per dimension */ - public abstract int getBytesPerDimension(String fieldName) throws IOException; + public abstract int getBytesPerDimension() throws IOException; - /** Returns the total number of indexed points across all documents in this field. */ - public abstract long size(String fieldName); + /** Returns the total number of indexed points across all documents. */ + public abstract long size(); - /** Returns the total number of documents that have indexed at least one point for this field. */ - public abstract int getDocCount(String fieldName); + /** Returns the total number of documents that have indexed at least one point. */ + public abstract int getDocCount(); } diff --git a/lucene/core/src/java/org/apache/lucene/index/PointValuesWriter.java b/lucene/core/src/java/org/apache/lucene/index/PointValuesWriter.java index daf1f338730..fc50d52a482 100644 --- a/lucene/core/src/java/org/apache/lucene/index/PointValuesWriter.java +++ b/lucene/core/src/java/org/apache/lucene/index/PointValuesWriter.java @@ -18,7 +18,7 @@ package org.apache.lucene.index; import java.io.IOException; -import org.apache.lucene.codecs.MutablePointsReader; +import org.apache.lucene.codecs.MutablePointValues; import org.apache.lucene.codecs.PointsReader; import org.apache.lucene.codecs.PointsWriter; import org.apache.lucene.util.ArrayUtil; @@ -70,7 +70,7 @@ class PointValuesWriter { } public void flush(SegmentWriteState state, PointsWriter writer) throws IOException { - PointsReader reader = new MutablePointsReader() { + PointValues values = new MutablePointValues() { final int[] ords = new int[numPoints]; { @@ -80,10 +80,7 @@ class PointValuesWriter { } @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { - if (fieldName.equals(fieldInfo.name) == false) { - throw new IllegalArgumentException("fieldName must be the same"); - } + public void intersect(IntersectVisitor visitor) throws IOException { final BytesRef scratch = new BytesRef(); final byte[] packedValue = new byte[packedBytesLength]; for(int i=0;i maxPointsInLeafNode) { @@ -465,7 +465,7 @@ public class BKDWriter implements Closeable { Arrays.fill(minPackedValue, (byte) 0xff); Arrays.fill(maxPackedValue, (byte) 0); for (int i = 0; i < Math.toIntExact(pointCount); ++i) { - reader.getValue(i, scratchBytesRef1); + values.getValue(i, scratchBytesRef1); for(int dim=0;dim Integer.MAX_VALUE); + assertTrue(r.leaves().get(0).reader().getPointValues("long").size() > Integer.MAX_VALUE); r.close(); w.close(); System.out.println("TEST: now CheckIndex"); @@ -126,7 +126,7 @@ public class Test2BPoints extends LuceneTestCase { DirectoryReader r = DirectoryReader.open(w); IndexSearcher s = new IndexSearcher(r); assertEquals(numDocs, s.count(LongPoint.newRangeQuery("long", new long[] {Long.MIN_VALUE, Long.MIN_VALUE}, new long[] {Long.MAX_VALUE, Long.MAX_VALUE}))); - assertTrue(r.leaves().get(0).reader().getPointValues().size("long") > Integer.MAX_VALUE); + assertTrue(r.leaves().get(0).reader().getPointValues("long").size() > Integer.MAX_VALUE); r.close(); w.close(); System.out.println("TEST: now CheckIndex"); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java index a75290a352b..7228f376009 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestPointValues.java @@ -503,8 +503,8 @@ public class TestPointValues extends LuceneTestCase { IndexReader r = DirectoryReader.open(w); for(LeafReaderContext ctx : r.leaves()) { - PointValues points = ctx.reader().getPointValues(); - points.intersect("int", + PointValues points = ctx.reader().getPointValues("int"); + points.intersect( new IntersectVisitor() { int lastDocID = -1; @@ -553,8 +553,7 @@ public class TestPointValues extends LuceneTestCase { w.forceMerge(1); DirectoryReader r = w.getReader(); - assertEquals(0, r.leaves().get(0).reader().getPointValues().size("int")); - assertEquals(0, r.leaves().get(0).reader().getPointValues().getDocCount("int")); + assertNull(r.leaves().get(0).reader().getPointValues("int")); w.close(); r.close(); dir.close(); @@ -611,10 +610,10 @@ public class TestPointValues extends LuceneTestCase { int size = 0; String fieldName = "int" + field; for(LeafReaderContext ctx : r.leaves()) { - PointValues points = ctx.reader().getPointValues(); - if (ctx.reader().getFieldInfos().fieldInfo(fieldName) != null) { - docCount += points.getDocCount(fieldName); - size += points.size(fieldName); + PointValues points = ctx.reader().getPointValues(fieldName); + if (points != null) { + docCount += points.getDocCount(); + size += points.size(); } } assertEquals(fieldDocCounts[field], docCount); @@ -738,7 +737,7 @@ public class TestPointValues extends LuceneTestCase { final IndexReader reader1 = DirectoryReader.open(w); w.forceMerge(1); final IndexReader reader2 = DirectoryReader.open(w); - final PointValues expected = getOnlyLeafReader(reader2).getPointValues(); + final PointValues expected = getOnlyLeafReader(reader2).getPointValues("field"); if (expected == null) { assertNull(PointValues.getMinPackedValue(reader1, "field")); assertNull(PointValues.getMaxPackedValue(reader1, "field")); @@ -746,13 +745,13 @@ public class TestPointValues extends LuceneTestCase { assertEquals(0, PointValues.size(reader1, "field")); } else { assertArrayEquals( - expected.getMinPackedValue("field"), + expected.getMinPackedValue(), PointValues.getMinPackedValue(reader1, "field")); assertArrayEquals( - expected.getMaxPackedValue("field"), + expected.getMaxPackedValue(), PointValues.getMaxPackedValue(reader1, "field")); - assertEquals(expected.getDocCount("field"), PointValues.getDocCount(reader1, "field")); - assertEquals(expected.size("field"), PointValues.size(reader1, "field")); + assertEquals(expected.getDocCount(), PointValues.getDocCount(reader1, "field")); + assertEquals(expected.size(), PointValues.size(reader1, "field")); } IOUtils.close(w, reader1, reader2, dir); } diff --git a/lucene/core/src/test/org/apache/lucene/util/TestDocIdSetBuilder.java b/lucene/core/src/test/org/apache/lucene/util/TestDocIdSetBuilder.java index 62e85fef088..625b8c24604 100644 --- a/lucene/core/src/test/org/apache/lucene/util/TestDocIdSetBuilder.java +++ b/lucene/core/src/test/org/apache/lucene/util/TestDocIdSetBuilder.java @@ -307,37 +307,37 @@ public class TestDocIdSetBuilder extends LuceneTestCase { } @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { + public void intersect(IntersectVisitor visitor) throws IOException { throw new UnsupportedOperationException(); } @Override - public byte[] getMinPackedValue(String fieldName) throws IOException { + public byte[] getMinPackedValue() throws IOException { throw new UnsupportedOperationException(); } @Override - public byte[] getMaxPackedValue(String fieldName) throws IOException { + public byte[] getMaxPackedValue() throws IOException { throw new UnsupportedOperationException(); } @Override - public int getNumDimensions(String fieldName) throws IOException { + public int getNumDimensions() throws IOException { throw new UnsupportedOperationException(); } @Override - public int getBytesPerDimension(String fieldName) throws IOException { + public int getBytesPerDimension() throws IOException { throw new UnsupportedOperationException(); } @Override - public long size(String fieldName) { + public long size() { return numPoints; } @Override - public int getDocCount(String fieldName) { + public int getDocCount() { return docCount; } diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java index 4616ce3901d..8d2ea3e16c9 100644 --- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java +++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.Comparator; -import org.apache.lucene.codecs.MutablePointsReader; +import org.apache.lucene.codecs.MutablePointValues; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.LuceneTestCase; @@ -184,7 +184,7 @@ public class TestMutablePointsReaderUtils extends LuceneTestCase { } } - private static class DummyPointsReader extends MutablePointsReader { + private static class DummyPointsReader extends MutablePointValues { private final Point[] points; @@ -192,16 +192,6 @@ public class TestMutablePointsReaderUtils extends LuceneTestCase { this.points = points.clone(); } - @Override - public void close() throws IOException { - throw new UnsupportedOperationException(); - } - - @Override - public long ramBytesUsed() { - return 0; - } - @Override public void getValue(int i, BytesRef packedValue) { packedValue.bytes = points[i].packedValue.bytes; @@ -226,42 +216,37 @@ public class TestMutablePointsReaderUtils extends LuceneTestCase { } @Override - public void checkIntegrity() throws IOException { + public void intersect(IntersectVisitor visitor) throws IOException { throw new UnsupportedOperationException(); } @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { + public byte[] getMinPackedValue() throws IOException { throw new UnsupportedOperationException(); } @Override - public byte[] getMinPackedValue(String fieldName) throws IOException { + public byte[] getMaxPackedValue() throws IOException { throw new UnsupportedOperationException(); } @Override - public byte[] getMaxPackedValue(String fieldName) throws IOException { + public int getNumDimensions() throws IOException { throw new UnsupportedOperationException(); } @Override - public int getNumDimensions(String fieldName) throws IOException { + public int getBytesPerDimension() throws IOException { throw new UnsupportedOperationException(); } @Override - public int getBytesPerDimension(String fieldName) throws IOException { + public long size() { throw new UnsupportedOperationException(); } @Override - public long size(String fieldName) { - throw new UnsupportedOperationException(); - } - - @Override - public int getDocCount(String fieldName) { + public int getDocCount() { throw new UnsupportedOperationException(); } diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/TermVectorLeafReader.java b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/TermVectorLeafReader.java index 07506f2051c..608e3d47128 100644 --- a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/TermVectorLeafReader.java +++ b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/TermVectorLeafReader.java @@ -144,7 +144,7 @@ public class TermVectorLeafReader extends LeafReader { } @Override - public PointValues getPointValues() { + public PointValues getPointValues(String fieldName) { return null; } diff --git a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java index f99f3183127..70c28d58f9f 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java @@ -140,10 +140,6 @@ abstract class PointInSetIncludingScoreQuery extends Query { @Override public Scorer scorer(LeafReaderContext context) throws IOException { LeafReader reader = context.reader(); - PointValues values = reader.getPointValues(); - if (values == null) { - return null; - } FieldInfo fieldInfo = reader.getFieldInfos().fieldInfo(field); if (fieldInfo == null) { return null; @@ -154,10 +150,14 @@ abstract class PointInSetIncludingScoreQuery extends Query { if (fieldInfo.getPointNumBytes() != bytesPerDim) { throw new IllegalArgumentException("field=\"" + field + "\" was indexed with bytesPerDim=" + fieldInfo.getPointNumBytes() + " but this query has bytesPerDim=" + bytesPerDim); } + PointValues values = reader.getPointValues(field); + if (values == null) { + return null; + } FixedBitSet result = new FixedBitSet(reader.maxDoc()); float[] scores = new float[reader.maxDoc()]; - values.intersect(field, new MergePointVisitor(sortedPackedPoints, result, scores)); + values.intersect(new MergePointVisitor(sortedPackedPoints, result, scores)); return new Scorer(this) { DocIdSetIterator disi = new BitSetIterator(result, 10L); diff --git a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index 8db9c9e6415..ccbbf243d76 100644 --- a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.SortedMap; import java.util.TreeMap; @@ -1065,22 +1066,12 @@ public class MemoryIndex { */ private final class MemoryIndexReader extends LeafReader { - private final PointValues pointValues; private Fields memoryFields = new MemoryFields(fields); private MemoryIndexReader() { super(); // avoid as much superclass baggage as possible - boolean hasPointValues = false; for (Info info : fields.values()) { info.prepareDocValuesAndPointValues(); - if (info.pointValues != null) { - hasPointValues = true; - } - } - if (hasPointValues) { - pointValues = new MemoryIndexPointValues(); - } else { - pointValues = null; } } @@ -1198,8 +1189,12 @@ public class MemoryIndex { } @Override - public PointValues getPointValues() { - return pointValues; + public PointValues getPointValues(String fieldName) { + Info info = fields.get(fieldName); + if (info.pointValues == null) { + return null; + } + return new MemoryIndexPointValues(info); } @Override @@ -1504,16 +1499,15 @@ public class MemoryIndex { private class MemoryIndexPointValues extends PointValues { + final Info info; + + MemoryIndexPointValues(Info info) { + this.info = Objects.requireNonNull(info); + } + @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { - Info info = fields.get(fieldName); - if (info == null) { - return; - } + public void intersect(IntersectVisitor visitor) throws IOException { BytesRef[] values = info.pointValues; - if (values == null) { - return; - } visitor.grow(info.pointValuesCount); for (int i = 0; i < info.pointValuesCount; i++) { @@ -1522,11 +1516,7 @@ public class MemoryIndex { } @Override - public byte[] getMinPackedValue(String fieldName) throws IOException { - Info info = fields.get(fieldName); - if (info == null) { - return null; - } + public byte[] getMinPackedValue() throws IOException { BytesRef[] values = info.pointValues; if (values != null) { return info.minPackedValue; @@ -1536,63 +1526,28 @@ public class MemoryIndex { } @Override - public byte[] getMaxPackedValue(String fieldName) throws IOException { - Info info = fields.get(fieldName); - if (info == null) { - return null; - } - BytesRef[] values = info.pointValues; - if (values != null) { - return info.maxPackedValue; - } else { - return null; - } + public byte[] getMaxPackedValue() throws IOException { + return info.maxPackedValue; } @Override - public int getNumDimensions(String fieldName) throws IOException { - Info info = fields.get(fieldName); - if (info == null){ - return 0; - } + public int getNumDimensions() throws IOException { return info.fieldInfo.getPointDimensionCount(); } @Override - public int getBytesPerDimension(String fieldName) throws IOException { - Info info = fields.get(fieldName); - if (info == null){ - return 0; - } + public int getBytesPerDimension() throws IOException { return info.fieldInfo.getPointNumBytes(); } @Override - public long size(String fieldName) { - Info info = fields.get(fieldName); - if (info == null) { - return 0; - } - BytesRef[] values = info.pointValues; - if (values != null) { - return info.pointValuesCount; - } else { - return 0; - } + public long size() { + return info.pointValuesCount; } @Override - public int getDocCount(String fieldName) { - Info info = fields.get(fieldName); - if (info == null) { - return 0; - } - BytesRef[] values = info.pointValues; - if (values != null) { - return 1; - } else { - return 0; - } + public int getDocCount() { + return 1; } } diff --git a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java index da3dd4c8f05..ab4fe21bbeb 100644 --- a/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java +++ b/lucene/memory/src/test/org/apache/lucene/index/memory/TestMemoryIndex.java @@ -479,9 +479,9 @@ public class TestMemoryIndex extends LuceneTestCase { MemoryIndex mi = MemoryIndex.fromDocument(doc, analyzer); LeafReader leafReader = mi.createSearcher().getIndexReader().leaves().get(0).reader(); - assertEquals(1, leafReader.getPointValues().size("field")); - assertArrayEquals(packedPoint, leafReader.getPointValues().getMinPackedValue("field")); - assertArrayEquals(packedPoint, leafReader.getPointValues().getMaxPackedValue("field")); + assertEquals(1, leafReader.getPointValues("field").size()); + assertArrayEquals(packedPoint, leafReader.getPointValues("field").getMinPackedValue()); + assertArrayEquals(packedPoint, leafReader.getPointValues("field").getMaxPackedValue()); BinaryDocValues dvs = leafReader.getBinaryDocValues("field"); assertEquals(0, dvs.nextDoc()); diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java index 19f80ab453d..1d3146e0b69 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.List; import org.apache.lucene.codecs.lucene60.Lucene60PointsFormat; -import org.apache.lucene.codecs.lucene60.Lucene60PointsReader; import org.apache.lucene.geo.GeoUtils; import org.apache.lucene.geo.Polygon; import org.apache.lucene.index.FieldInfo; @@ -307,13 +306,13 @@ public class LatLonPoint extends Field { List liveDocs = new ArrayList<>(); int totalHits = 0; for(LeafReaderContext leaf : searcher.getIndexReader().leaves()) { - PointValues points = leaf.reader().getPointValues(); + PointValues points = leaf.reader().getPointValues(field); if (points != null) { - if (points instanceof Lucene60PointsReader == false) { + if (points instanceof BKDReader == false) { throw new IllegalArgumentException("can only run on Lucene60PointsReader points implementation, but got " + points); } - totalHits += points.getDocCount(field); - BKDReader reader = ((Lucene60PointsReader) points).getBKDReader(field); + totalHits += points.getDocCount(); + BKDReader reader = (BKDReader) points; if (reader != null) { readers.add(reader); docBases.add(leaf.docBase); diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java index 1b20d9563d7..7a00cefbbee 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java @@ -105,7 +105,7 @@ final class LatLonPointDistanceQuery extends Query { @Override public Scorer scorer(LeafReaderContext context) throws IOException { LeafReader reader = context.reader(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); if (values == null) { // No docs in this segment had any points fields return null; @@ -120,7 +120,7 @@ final class LatLonPointDistanceQuery extends Query { // matching docids DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field); - values.intersect(field, + values.intersect( new IntersectVisitor() { DocIdSetBuilder.BulkAdder adder; diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java index 036fe2cf0d0..ec7c682cd73 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java @@ -98,7 +98,7 @@ final class LatLonPointInPolygonQuery extends Query { @Override public Scorer scorer(LeafReaderContext context) throws IOException { LeafReader reader = context.reader(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); if (values == null) { // No docs in this segment had any points fields return null; @@ -113,7 +113,7 @@ final class LatLonPointInPolygonQuery extends Query { // matching docids DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field); - values.intersect(field, + values.intersect( new IntersectVisitor() { DocIdSetBuilder.BulkAdder adder; diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java index 1fa894fcbc6..7ebdec491ee 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/RangeFieldQuery.java @@ -110,7 +110,7 @@ abstract class RangeFieldQuery extends Query { final RangeFieldComparator comparator = new RangeFieldComparator(); private DocIdSet buildMatchingDocIdSet(LeafReader reader, PointValues values) throws IOException { DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field); - values.intersect(field, + values.intersect( new IntersectVisitor() { DocIdSetBuilder.BulkAdder adder; @Override @@ -157,7 +157,7 @@ abstract class RangeFieldQuery extends Query { @Override public Scorer scorer(LeafReaderContext context) throws IOException { LeafReader reader = context.reader(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); if (values == null) { // no docs in this segment indexed any ranges return null; @@ -168,9 +168,9 @@ abstract class RangeFieldQuery extends Query { } checkFieldInfo(fieldInfo); boolean allDocsMatch = true; - if (values.getDocCount(field) == reader.maxDoc()) { + if (values.getDocCount() == reader.maxDoc()) { // if query crosses, docs need to be further scrutinized - byte[] range = getInternalRange(values.getMinPackedValue(field), values.getMaxPackedValue(field)); + byte[] range = getInternalRange(values.getMinPackedValue(), values.getMaxPackedValue()); // if the internal node is not equal and not contained by the query, all docs do not match if ((!Arrays.equals(ranges, range) && (comparator.contains(range) && queryType != QueryType.CONTAINS)) == false) { diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java index 105e5d88308..56cb45d92d4 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java @@ -70,7 +70,7 @@ final class PointInGeo3DShapeQuery extends Query { @Override public Scorer scorer(LeafReaderContext context) throws IOException { LeafReader reader = context.reader(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); if (values == null) { return null; } @@ -99,7 +99,7 @@ final class PointInGeo3DShapeQuery extends Query { DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field); - values.intersect(field, new PointInShapeIntersectVisitor(result, shape, shapeBounds)); + values.intersect(new PointInShapeIntersectVisitor(result, shape, shapeBounds)); return new ConstantScoreScorer(this, score(), result.build().iterator()); } diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java index 97606c70a01..2af096adc3f 100644 --- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java +++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java @@ -1486,11 +1486,11 @@ public class TestGeo3DPoint extends LuceneTestCase { docID - reader.leaves().get(subIndex).docBase, 3, Integer.BYTES, b); // Do first phase, where we just figure out the "path" that leads to the target docID: - leafReader.getPointValues().intersect(fieldName, visitor); + leafReader.getPointValues(fieldName).intersect(visitor); // Do second phase, where we we see how the wrapped visitor responded along that path: visitor.startSecondPhase(); - leafReader.getPointValues().intersect(fieldName, visitor); + leafReader.getPointValues(fieldName).intersect(visitor); return b.toString(); } diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointsFormat.java index c6f5485202a..ff2e1b61361 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointsFormat.java +++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPointsFormat.java @@ -22,16 +22,13 @@ import java.util.Collection; import org.apache.lucene.codecs.PointsFormat; import org.apache.lucene.codecs.PointsReader; import org.apache.lucene.codecs.PointsWriter; +import org.apache.lucene.index.AssertingLeafReader; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.MergeState; -import org.apache.lucene.index.PointValues.IntersectVisitor; -import org.apache.lucene.index.PointValues.Relation; import org.apache.lucene.index.PointValues; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.util.Accountable; -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.TestUtil; /** @@ -66,88 +63,6 @@ public final class AssertingPointsFormat extends PointsFormat { return new AssertingPointsReader(state.segmentInfo.maxDoc(), in.fieldsReader(state)); } - /** Validates in the 1D case that all points are visited in order, and point values are in bounds of the last cell checked */ - static class AssertingIntersectVisitor implements IntersectVisitor { - final IntersectVisitor in; - final int numDims; - final int bytesPerDim; - final byte[] lastDocValue; - final byte[] lastMinPackedValue; - final byte[] lastMaxPackedValue; - private Relation lastCompareResult; - private int lastDocID = -1; - private int docBudget; - - public AssertingIntersectVisitor(int numDims, int bytesPerDim, IntersectVisitor in) { - this.in = in; - this.numDims = numDims; - this.bytesPerDim = bytesPerDim; - lastMaxPackedValue = new byte[numDims*bytesPerDim]; - lastMinPackedValue = new byte[numDims*bytesPerDim]; - if (numDims == 1) { - lastDocValue = new byte[bytesPerDim]; - } else { - lastDocValue = null; - } - } - - @Override - public void visit(int docID) throws IOException { - assert --docBudget >= 0 : "called add() more times than the last call to grow() reserved"; - - // This method, not filtering each hit, should only be invoked when the cell is inside the query shape: - assert lastCompareResult == Relation.CELL_INSIDE_QUERY; - in.visit(docID); - } - - @Override - public void visit(int docID, byte[] packedValue) throws IOException { - assert --docBudget >= 0 : "called add() more times than the last call to grow() reserved"; - - // This method, to filter each doc's value, should only be invoked when the cell crosses the query shape: - assert lastCompareResult == PointValues.Relation.CELL_CROSSES_QUERY; - - // This doc's packed value should be contained in the last cell passed to compare: - for(int dim=0;dim= 0; - assert in.getDocCount(fieldName) >= 0; - assert in.getDocCount(fieldName) <= in.size(fieldName); - assert in.getDocCount(fieldName) <= maxDoc; - } } static class AssertingPointsWriter extends PointsWriter { diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/cranky/CrankyPointsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/cranky/CrankyPointsFormat.java index fd2260be6a5..ec7d75ae1c7 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/codecs/cranky/CrankyPointsFormat.java +++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/cranky/CrankyPointsFormat.java @@ -24,6 +24,7 @@ import org.apache.lucene.codecs.PointsReader; import org.apache.lucene.codecs.PointsWriter; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.MergeState; +import org.apache.lucene.index.PointValues; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.SegmentWriteState; @@ -114,46 +115,67 @@ class CrankyPointsFormat extends PointsFormat { } @Override - public void intersect(String fieldName, IntersectVisitor visitor) throws IOException { - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); + public PointValues getValues(String fieldName) throws IOException { + final PointValues delegate = this.delegate.getValues(fieldName); + if (delegate == null) { + return null; } - delegate.intersect(fieldName, visitor); - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); - } - } + return new PointValues() { - @Override - public byte[] getMinPackedValue(String fieldName) throws IOException { - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); - } - return delegate.getMinPackedValue(fieldName); - } + @Override + public void intersect(IntersectVisitor visitor) throws IOException { + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + delegate.intersect(visitor); + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + } - @Override - public byte[] getMaxPackedValue(String fieldName) throws IOException { - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); - } - return delegate.getMaxPackedValue(fieldName); - } + @Override + public byte[] getMinPackedValue() throws IOException { + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + return delegate.getMinPackedValue(); + } - @Override - public int getNumDimensions(String fieldName) throws IOException { - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); - } - return delegate.getNumDimensions(fieldName); - } + @Override + public byte[] getMaxPackedValue() throws IOException { + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + return delegate.getMaxPackedValue(); + } - @Override - public int getBytesPerDimension(String fieldName) throws IOException { - if (random.nextInt(100) == 0) { - throw new IOException("Fake IOException"); - } - return delegate.getBytesPerDimension(fieldName); + @Override + public int getNumDimensions() throws IOException { + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + return delegate.getNumDimensions(); + } + + @Override + public int getBytesPerDimension() throws IOException { + if (random.nextInt(100) == 0) { + throw new IOException("Fake IOException"); + } + return delegate.getBytesPerDimension(); + } + + @Override + public long size() { + return delegate.size(); + } + + @Override + public int getDocCount() { + return delegate.getDocCount(); + } + + }; } @Override @@ -168,15 +190,5 @@ class CrankyPointsFormat extends PointsFormat { public long ramBytesUsed() { return delegate.ramBytesUsed(); } - - @Override - public long size(String fieldName) { - return delegate.size(fieldName); - } - - @Override - public int getDocCount(String fieldName) { - return delegate.getDocCount(fieldName); - } } } diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java b/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java index b2958c8bb38..6686ec4778e 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java +++ b/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java @@ -18,10 +18,14 @@ package org.apache.lucene.index; import java.io.IOException; import java.util.Iterator; +import java.util.Objects; +import org.apache.lucene.index.PointValues.IntersectVisitor; +import org.apache.lucene.index.PointValues.Relation; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.VirtualMethod; import org.apache.lucene.util.automaton.CompiledAutomaton; @@ -776,7 +780,145 @@ public class AssertingLeafReader extends FilterLeafReader { return result; } } - + + /** Wraps a SortedSetDocValues but with additional asserts */ + public static class AssertingPointValues extends PointValues { + + private final PointValues in; + + /** Sole constructor. */ + public AssertingPointValues(PointValues in, int maxDoc) { + this.in = in; + assertStats(maxDoc); + } + + private void assertStats(int maxDoc) { + assert in.size() > 0; + assert in.getDocCount() > 0; + assert in.getDocCount() <= in.size(); + assert in.getDocCount() <= maxDoc; + } + + @Override + public void intersect(IntersectVisitor visitor) throws IOException { + in.intersect(new AssertingIntersectVisitor(in.getNumDimensions(), in.getBytesPerDimension(), visitor)); + } + + @Override + public byte[] getMinPackedValue() throws IOException { + return Objects.requireNonNull(in.getMinPackedValue()); + } + + @Override + public byte[] getMaxPackedValue() throws IOException { + return Objects.requireNonNull(in.getMaxPackedValue()); + } + + @Override + public int getNumDimensions() throws IOException { + return in.getNumDimensions(); + } + + @Override + public int getBytesPerDimension() throws IOException { + return in.getBytesPerDimension(); + } + + @Override + public long size() { + return in.size(); + } + + @Override + public int getDocCount() { + return in.getDocCount(); + } + + } + + /** Validates in the 1D case that all points are visited in order, and point values are in bounds of the last cell checked */ + static class AssertingIntersectVisitor implements IntersectVisitor { + final IntersectVisitor in; + final int numDims; + final int bytesPerDim; + final byte[] lastDocValue; + final byte[] lastMinPackedValue; + final byte[] lastMaxPackedValue; + private Relation lastCompareResult; + private int lastDocID = -1; + private int docBudget; + + AssertingIntersectVisitor(int numDims, int bytesPerDim, IntersectVisitor in) { + this.in = in; + this.numDims = numDims; + this.bytesPerDim = bytesPerDim; + lastMaxPackedValue = new byte[numDims*bytesPerDim]; + lastMinPackedValue = new byte[numDims*bytesPerDim]; + if (numDims == 1) { + lastDocValue = new byte[bytesPerDim]; + } else { + lastDocValue = null; + } + } + + @Override + public void visit(int docID) throws IOException { + assert --docBudget >= 0 : "called add() more times than the last call to grow() reserved"; + + // This method, not filtering each hit, should only be invoked when the cell is inside the query shape: + assert lastCompareResult == Relation.CELL_INSIDE_QUERY; + in.visit(docID); + } + + @Override + public void visit(int docID, byte[] packedValue) throws IOException { + assert --docBudget >= 0 : "called add() more times than the last call to grow() reserved"; + + // This method, to filter each doc's value, should only be invoked when the cell crosses the query shape: + assert lastCompareResult == PointValues.Relation.CELL_CROSSES_QUERY; + + // This doc's packed value should be contained in the last cell passed to compare: + for(int dim=0;dim> docValues = new HashMap<>(); for(LeafReaderContext ctx : reader.leaves()) { - PointValues points = ctx.reader().getPointValues(); + PointValues points = ctx.reader().getPointValues(fieldName); if (points == null) { continue; } - points.intersect(fieldName, + points.intersect( new PointValues.IntersectVisitor() { @Override public void visit(int docID) { diff --git a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java index 7c7098cdc76..5031faf0125 100644 --- a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java +++ b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java @@ -237,7 +237,7 @@ public final class SlowCompositeReaderWrapper extends LeafReader { } @Override - public PointValues getPointValues() { + public PointValues getPointValues(String field) { ensureOpen(); return null; } diff --git a/solr/core/src/java/org/apache/solr/uninverting/FieldCacheImpl.java b/solr/core/src/java/org/apache/solr/uninverting/FieldCacheImpl.java index f06f7e3fb03..b63e5e93365 100644 --- a/solr/core/src/java/org/apache/solr/uninverting/FieldCacheImpl.java +++ b/solr/core/src/java/org/apache/solr/uninverting/FieldCacheImpl.java @@ -277,12 +277,12 @@ class FieldCacheImpl implements FieldCache { final void uninvertPoints(LeafReader reader, String field) throws IOException { final int maxDoc = reader.maxDoc(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); assert values != null; - assert values.size(field) > 0; + assert values.size() > 0; final boolean setDocsWithField; - final int docCount = values.getDocCount(field); + final int docCount = values.getDocCount(); assert docCount <= maxDoc; if (docCount == maxDoc) { // Fast case: all docs have this field: @@ -293,7 +293,7 @@ class FieldCacheImpl implements FieldCache { } BytesRef scratch = new BytesRef(); - values.intersect(field, new IntersectVisitor() { + values.intersect(new IntersectVisitor() { @Override public void visit(int docID) throws IOException { throw new AssertionError(); @@ -512,11 +512,11 @@ class FieldCacheImpl implements FieldCache { private BitsEntry createValuePoints(LeafReader reader, String field) throws IOException { final int maxDoc = reader.maxDoc(); - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); assert values != null; - assert values.size(field) > 0; + assert values.size() > 0; - final int docCount = values.getDocCount(field); + final int docCount = values.getDocCount(); assert docCount <= maxDoc; if (docCount == maxDoc) { // Fast case: all docs have this field: @@ -615,14 +615,14 @@ class FieldCacheImpl implements FieldCache { if (info.getPointDimensionCount() != 1) { throw new IllegalStateException("Type mismatch: " + field + " was indexed with dimensions=" + info.getPointDimensionCount()); } - PointValues values = reader.getPointValues(); + PointValues values = reader.getPointValues(field); // no actual points for this field (e.g. all points deleted) - if (values == null || values.size(field) == 0) { + if (values == null || values.size() == 0) { return DocValues.emptyNumeric(); } // not single-valued - if (values.size(field) != values.getDocCount(field)) { - throw new IllegalStateException("Type mismatch: " + field + " was indexed with multiple values, numValues=" + values.size(field) + ",numDocs=" + values.getDocCount(field)); + if (values.size() != values.getDocCount()) { + throw new IllegalStateException("Type mismatch: " + field + " was indexed with multiple values, numValues=" + values.size() + ",numDocs=" + values.getDocCount()); } } else { // postings case diff --git a/solr/core/src/test/org/apache/solr/search/TestDocSet.java b/solr/core/src/test/org/apache/solr/search/TestDocSet.java index 5b445147754..2849f09a2ce 100644 --- a/solr/core/src/test/org/apache/solr/search/TestDocSet.java +++ b/solr/core/src/test/org/apache/solr/search/TestDocSet.java @@ -448,7 +448,7 @@ public class TestDocSet extends LuceneTestCase { } @Override - public PointValues getPointValues() { + public PointValues getPointValues(String field) { return null; }