diff --git a/lucene/core/src/java/org/apache/lucene/index/BinaryDocValues.java b/lucene/core/src/java/org/apache/lucene/index/BinaryDocValues.java index 57ae465120a..9e6431d8b9d 100644 --- a/lucene/core/src/java/org/apache/lucene/index/BinaryDocValues.java +++ b/lucene/core/src/java/org/apache/lucene/index/BinaryDocValues.java @@ -36,10 +36,12 @@ public abstract class BinaryDocValues { */ public static final byte[] MISSING = new byte[0]; - /** An empty BinaryDocValues which returns empty bytes for every document */ + /** An empty BinaryDocValues which returns {@link #MISSING} for every document */ public static final BinaryDocValues EMPTY = new BinaryDocValues() { @Override public void get(int docID, BytesRef result) { + result.bytes = MISSING; + result.offset = 0; result.length = 0; } }; diff --git a/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java b/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java index 360df524ffd..34dc4c7b1f8 100644 --- a/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java +++ b/lucene/core/src/java/org/apache/lucene/index/MultiDocValues.java @@ -51,61 +51,82 @@ public class MultiDocValues { /** No instantiation */ private MultiDocValues() {} - /** returns a NumericDocValues for a reader's norms (potentially merging on-the-fly) */ - // moved to src/java so SlowWrapper can use it... uggggggh + /** Returns a NumericDocValues for a reader's norms (potentially merging on-the-fly). + *

+ * This is a slow way to access normalization values. Instead, access them per-segment + * with {@link AtomicReader#getNormValues(String)} + *

+ */ public static NumericDocValues getNormValues(final IndexReader r, final String field) throws IOException { final List leaves = r.leaves(); - if (leaves.size() == 1) { + final int size = leaves.size(); + if (size == 0) { + return null; + } else if (size == 1) { return leaves.get(0).reader().getNormValues(field); } FieldInfo fi = MultiFields.getMergedFieldInfos(r).fieldInfo(field); if (fi == null || fi.hasNorms() == false) { return null; } - boolean anyReal = false; - for(AtomicReaderContext ctx : leaves) { - NumericDocValues norms = ctx.reader().getNormValues(field); - if (norms != null) { + boolean anyReal = false; + final NumericDocValues[] values = new NumericDocValues[size]; + final int[] starts = new int[size+1]; + for (int i = 0; i < size; i++) { + AtomicReaderContext context = leaves.get(i); + NumericDocValues v = context.reader().getNormValues(field); + if (v == null) { + v = NumericDocValues.EMPTY; + } else { anyReal = true; } + values[i] = v; + starts[i] = context.docBase; } - + starts[size] = r.maxDoc(); + assert anyReal; return new NumericDocValues() { @Override public long get(int docID) { - int subIndex = ReaderUtil.subIndex(docID, leaves); - NumericDocValues norms; - try { - norms = leaves.get(subIndex).reader().getNormValues(field); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - if (norms == null) { - return 0; - } else { - return norms.get(docID - leaves.get(subIndex).docBase); - } + int subIndex = ReaderUtil.subIndex(docID, starts); + return values[subIndex].get(docID - starts[subIndex]); } }; } - /** returns a NumericDocValues for a reader's docvalues (potentially merging on-the-fly) */ + /** Returns a NumericDocValues for a reader's docvalues (potentially merging on-the-fly) + *

+ * This is a slow way to access numeric values. Instead, access them per-segment + * with {@link AtomicReader#getNumericDocValues(String)} + *

+ * */ public static NumericDocValues getNumericValues(final IndexReader r, final String field) throws IOException { final List leaves = r.leaves(); - if (leaves.size() == 1) { + final int size = leaves.size(); + if (size == 0) { + return null; + } else if (size == 1) { return leaves.get(0).reader().getNumericDocValues(field); } - boolean anyReal = false; - for(AtomicReaderContext ctx : leaves) { - NumericDocValues values = ctx.reader().getNumericDocValues(field); - if (values != null) { + boolean anyReal = false; + final NumericDocValues[] values = new NumericDocValues[size]; + final int[] starts = new int[size+1]; + for (int i = 0; i < size; i++) { + AtomicReaderContext context = leaves.get(i); + NumericDocValues v = context.reader().getNumericDocValues(field); + if (v == null) { + v = NumericDocValues.EMPTY; + } else { anyReal = true; } + values[i] = v; + starts[i] = context.docBase; } + starts[size] = r.maxDoc(); if (!anyReal) { return null; @@ -113,66 +134,64 @@ public class MultiDocValues { return new NumericDocValues() { @Override public long get(int docID) { - int subIndex = ReaderUtil.subIndex(docID, leaves); - NumericDocValues values; - try { - values = leaves.get(subIndex).reader().getNumericDocValues(field); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - if (values == null) { - return 0; - } else { - return values.get(docID - leaves.get(subIndex).docBase); - } + int subIndex = ReaderUtil.subIndex(docID, starts); + return values[subIndex].get(docID - starts[subIndex]); } }; } } - /** returns a BinaryDocValues for a reader's docvalues (potentially merging on-the-fly) */ + /** Returns a BinaryDocValues for a reader's docvalues (potentially merging on-the-fly) + *

+ * This is a slow way to access binary values. Instead, access them per-segment + * with {@link AtomicReader#getBinaryDocValues(String)} + *

+ */ public static BinaryDocValues getBinaryValues(final IndexReader r, final String field) throws IOException { final List leaves = r.leaves(); - if (leaves.size() == 1) { + final int size = leaves.size(); + + if (size == 0) { + return null; + } else if (size == 1) { return leaves.get(0).reader().getBinaryDocValues(field); } + boolean anyReal = false; - - for(AtomicReaderContext ctx : leaves) { - BinaryDocValues values = ctx.reader().getBinaryDocValues(field); - - if (values != null) { + final BinaryDocValues[] values = new BinaryDocValues[size]; + final int[] starts = new int[size+1]; + for (int i = 0; i < size; i++) { + AtomicReaderContext context = leaves.get(i); + BinaryDocValues v = context.reader().getBinaryDocValues(field); + if (v == null) { + v = BinaryDocValues.EMPTY; + } else { anyReal = true; } + values[i] = v; + starts[i] = context.docBase; } - + starts[size] = r.maxDoc(); + if (!anyReal) { return null; } else { - return new BinaryDocValues() { @Override public void get(int docID, BytesRef result) { - int subIndex = ReaderUtil.subIndex(docID, leaves); - BinaryDocValues values; - try { - values = leaves.get(subIndex).reader().getBinaryDocValues(field); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - if (values != null) { - values.get(docID - leaves.get(subIndex).docBase, result); - } else { - result.length = 0; - result.offset = 0; - result.bytes = BinaryDocValues.MISSING; - } + int subIndex = ReaderUtil.subIndex(docID, starts); + values[subIndex].get(docID - starts[subIndex], result); } }; } } - /** returns a SortedDocValues for a reader's docvalues (potentially doing extremely slow things) */ + /** Returns a SortedDocValues for a reader's docvalues (potentially doing extremely slow things). + *

+ * This is an extremely slow way to access sorted values. Instead, access them per-segment + * with {@link AtomicReader#getSortedDocValues(String)} + *

+ */ public static SortedDocValues getSortedValues(final IndexReader r, final String field) throws IOException { final List leaves = r.leaves(); if (leaves.size() == 1) { diff --git a/lucene/core/src/java/org/apache/lucene/index/SortedDocValues.java b/lucene/core/src/java/org/apache/lucene/index/SortedDocValues.java index 209cd67bfe9..ebdab6e8268 100644 --- a/lucene/core/src/java/org/apache/lucene/index/SortedDocValues.java +++ b/lucene/core/src/java/org/apache/lucene/index/SortedDocValues.java @@ -67,7 +67,7 @@ public abstract class SortedDocValues extends BinaryDocValues { } } - /** An empty SortedDocValues which returns empty bytes for every document */ + /** An empty SortedDocValues which returns {@link #MISSING} for every document */ public static final SortedDocValues EMPTY = new SortedDocValues() { @Override public int getOrd(int docID) { @@ -76,6 +76,8 @@ public abstract class SortedDocValues extends BinaryDocValues { @Override public void lookupOrd(int ord, BytesRef result) { + result.bytes = MISSING; + result.offset = 0; result.length = 0; }