lucene中的docValue实现源码解读(9)——SortedNumericDocValue的读取
lucene中的docValue实现源码解读(九)——SortedNumericDocValue的读取
再看具体的读取过程之前,先看一下SortedNumericDocValue接口的功能吧,
public abstract class SortedNumericDocValues { /** Sole constructor. (For invocation by subclass constructors, typically implicit.) */ protected SortedNumericDocValues() {} /** 定位到某个doc */ public abstract void setDocument(int doc); /** 返回当前的doc的第几个数字 */ public abstract long valueAt(int index); /** 当前的doc的值的个数 */ public abstract int count(); }
可以发现,其实SortedNumericDocValue提供的接口的功能很少,仅仅是得到某个doc的所有的数字。通过上一篇博客,自己也能猜出他的实现原理。
下面看看真正的读取操作,方法在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) {//所有的doc的值只有一个的情况。忽略 final Bits docsWithField = getMissingBits(numericEntry.missingOffset); return DocValues.singleton(values, docsWithField); } else if (ss.format == SORTED_WITH_ADDRESSES) {// //读取第二部分,即每个doc的第一个值是所有的值的第多少个。 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);//要查找的doc的值的偏移量 endOffset = ordIndex.get(doc + 1L);//要查找的doc的下一个doc的开始位置,也就是这个doc的结束位置 } @Override public long valueAt(int index) {//读取当前的doc的第n个值。 return values.get(startOffset + index); } @Override public int count() {//当前的doc一共多少个值 return (int) (endOffset - startOffset); } }; } else { throw new AssertionError(); } }
可以发现,读取SortedNumericDocValue其实是很简单的,用第二部分确定某个doc的值的开始位置和结束位置,也就是偏移量,然后再根据偏移量读取某个doc的值。