postings的存储, 读取, 缓存
一个term的postings list 存储
1: sort
2: delta
3: 每128个docID, 按block存储. block记录bits per value(该block最大值的bits, like fdx)
4: skipper(for boolean)
bitpacking代码(新优化):
Lucene84PostingsWriter.startDoc
ForUtil(SIMD):根据bitsPerValue大小,一次性将多个delta packed到一个long(64bits, rust使用128bits)中.
其他:PForUtil写freqs。ForDeltaUtil写deltas(调用ForUtil)。
从disk(os cache)按照postings list的delta写入方式读取, 读取后缓存
BitDocIdSet(bit map)
dense: postings length * 100 >= maxDoc(segment total docs)时使用。否则,
RoaringDocIdSet(roaring bitmap)
代码:
LRUQueryCache.cacheImpl
bit map
直接使用bitmap时, bitSet length为固定的segment total docs。
对于元素少的postings, 浪费空间。
roaring bitmap
1: docID除以65536, 商N(高2byte, max:32767), 余n(低2byte, max:65535), 将n写入block N。
N = docID >> 16, n = docID & 0xFFFF.
如:1000 62101 131385 132052 191173 196658.
block 0: 1000 62101.
block 1: null.
block 2: 313 980 60101.
block 3: 50.
2: 每个block独立处理。
当block中数量小于4096(2^12)时, 使用数组(short[]).
否则, 使用bitmap. bitSet length为固定的65535。
参考:
Of bitpacking with(rust tantivy) or without(java lucene) SSE3
https://fulmicoton.com/posts/bitpacking/
roaring-bitmaps
https://www.elastic.co/cn/blog/frame-of-reference-and-roaring-bitmaps
for, array,bitmap,roaring bitmap对比(iterator next, skip advance, memory)
http://people.apache.org/~jpountz/doc_id_sets4.html