lucene中的docValue实现源码解读(十一)——SortedSet的读取

阅读更多

对于SetDocValue的读取很简单,因为他的写入的格式和之前的SortedDocValue和SortedNumericDocValue有很多重复的地方,所以在读取的时候也是有很多重复的地方。

先看看最终要返回的接口吧,

public abstract class SortedSetDocValues {

	/** Sole constructor. (For invocation by subclass constructors, typically implicit.) */
	protected SortedSetDocValues() {}

	/*** When returned by {@link #nextOrd()} it means there are no more ordinals for the document. */
	public static final long NO_MORE_ORDS = -1;

	/** 读取当前的doc的下一个byte[]的排序 */
	public abstract long nextOrd();

	/** 设置要读取的doc的id */
	public abstract void setDocument(int docID);

	/**	查找指定排序的byte[] */
	public abstract BytesRef lookupOrd(long ord);

	/** 返回所有的byte[]的个数 */
	public abstract long getValueCount();

	/** 查询某个byte[]是否存在,如果不存在返回一个负数,这个方法被覆写了 */
	public long lookupTerm(BytesRef key) {
		long low = 0;
		long high = getValueCount() - 1;

		while (low <= high) {
			long mid = (low + high) >>> 1;
			final BytesRef term = lookupOrd(mid);
			int cmp = term.compareTo(key);

			if (cmp < 0) {
				low = mid + 1;
			} else if (cmp > 0) {
				high = mid - 1;
			} else {
				return mid; // key found
			}
		}
		return -(low + 1); // key not found.
	}

	/** 返回迭代所有的byte[]的对象 ,这个方法也被覆写了*/
	public TermsEnum termsEnum() {
		return new SortedSetDocValuesTermsEnum(this);
	}
}

 上面的功能很简单,基本和之前的SortedDocValue和SortedNumericDocValue一样。再看看具体的操作:

public SortedSetDocValues getSortedSet(FieldInfo field) throws IOException {
	
	SortedSetEntry ss = sortedSets.get(field.number);
	if (ss.format == SORTED_SINGLE_VALUED) {
		final SortedDocValues values = getSorted(field);
		return DocValues.singleton(values);
	} else if (ss.format != SORTED_WITH_ADDRESSES) {
		throw new AssertionError();
	}
	final long valueCount = binaries.get(field.number).count;//所有的byte[]的个数
	// we keep the byte[]s and list of ords on disk, these could be large
	final LongBinaryDocValues binary = (LongBinaryDocValues) getBinary(field);//获得所有的byte[]。
	final LongValues ordinals = getNumeric(ords.get(field.number));//读取第二部分,也就是每个doc的所有的排序的地方,
	
	// but the addresses to the ord stream are in RAM, 读取第三部分,即地址部分,用于计算每个doc的排序的地址
	final MonotonicBlockPackedReader ordIndex = getOrdIndexInstance(field, ordIndexes.get(field.number));
	
	return new RandomAccessOrds() {
		long startOffset;//当前的doc的第一个byte[]是总的byte[]的多少个。
		long offset;//
		long endOffset;//当前的doc的下一个doc的第一个byte[]是总的byte[]的多少个。
		public long nextOrd() {//读取当前doc的下一个byte的排序
			if (offset == endOffset) {
				return NO_MORE_ORDS;
			} else {
				long ord = ordinals.get(offset);
				offset++;
				return ord;
			}
		}
		public void setDocument(int docID) {//读取指定的doc,
			startOffset = offset = ordIndex.get(docID);
			endOffset = ordIndex.get(docID + 1L);
		}
		@Override
		public BytesRef lookupOrd(long ord) {//根据排序获得byte[]
			return binary.get(ord);
		}
		@Override
		public long getValueCount() {//所有的byte[]的个数
			return valueCount;
		}
		@Override
		public long lookupTerm(BytesRef key) {//返回一个byte[]是否存在,如果存在返回其排序,否则返回一个负数
			if (binary instanceof CompressedBinaryDocValues) {//进入
				return ((CompressedBinaryDocValues) binary).lookupTerm(key);
			} else {
				return super.lookupTerm(key);
			}
		}
		@Override
		public TermsEnum termsEnum() {
			if (binary instanceof CompressedBinaryDocValues) {//这个是进入的,因为在存储所有的byte[]的时候,就是前缀压缩的,和之前的SortedDocValue的格式是一样的,所以返回的结果也是一样的
				return ((CompressedBinaryDocValues) binary).getTermsEnum();
			} else {
				return super.termsEnum();
			}
		}
		@Override
		public long ordAt(int index) {
			return ordinals.get(startOffset + index);
		}
		@Override
		public int cardinality() {
			return (int) (endOffset - startOffset);
		}
	};
}

 如果看懂了SortedDocValue其实这里也很简单。

过年夜,少写点。。

 

 

你可能感兴趣的:(lucene,docValue,SortedSet,存储格式)