Before looking at the specific reading process, let's take a look at the functions of the SortedNumericDocValue interface.
public abstract class SortedNumericDocValues { /** Sole constructor. (For invocation by subclass constructors, typically implicit.) */ protected SortedNumericDocValues() {} /** locate a doc */ public abstract void setDocument(int doc); /** Returns the number of the current doc */ public abstract long valueAt(int index); /** The number of current doc values */ public abstract int count(); }
It can be found that, in fact, the interface provided by SortedNumericDocValue has very few functions, only to get all the numbers of a doc. Through the previous blog, I can also guess the principle of his implementation.
Let's take a look at the real read operation, the method is in Lucene410DocValuesProducer.getSortedNumeric(FieldInfo):
public SortedNumericDocValues getSortedNumeric(FieldInfo field) throws IOException { SortedSetEntry ss = sortedNumerics.get(field.number); NumericEntry numericEntry = numerics.get(field.number); final LongValues values = getNumeric(numericEntry); if (ss.format == SORTED_SINGLE_VALUED) {//All doc values are only one case. neglect final Bits docsWithField = getMissingBits(numericEntry.missingOffset); return DocValues.singleton(values, docsWithField); } else if (ss.format == SORTED_WITH_ADDRESSES) {// //Read the second part, that is, the first value of each doc is the number of all the values. final MonotonicBlockPackedReader ordIndex = getOrdIndexInstance(field, ordIndexes.get(field.number)); return new SortedNumericDocValues() { long startOffset; long endOffset; @Override public void setDocument(int doc) { startOffset = ordIndex.get(doc);//The offset of the value of the doc to be found endOffset = ordIndex.get(doc + 1L);//The start position of the next doc of the doc to be found, which is the end position of this doc } @Override public long valueAt(int index) {//Read the nth value of the current doc. return values.get(startOffset + index); } @Override public int count() {//How many values are there in the current doc return (int) (endOffset - startOffset); } }; } else { throw new AssertionError(); } }
It can be found that reading SortedNumericDocValue is actually very simple. Use the second part to determine the start position and end position of the value of a doc, that is, the offset, and then read the value of a doc according to the offset.