本文的代码以lucene-core 6.3.0为准,包含MinShouldMatchSumScorer的
iterator
函数和执行原理。转载请注明出处。
0 基本信息
- 对于每个迭代器而言,cost()代表这个迭代器的迭代路径长度,对于倒排表的迭代器,cost()返回的是倒排表的长度。
lead
变量是链表,存的迭代器的当前位置的docId都相等。tail
变量是堆结构, 按照迭代器的cost构建的小顶堆。head
变量是优先队列,按照迭代器当前位置的docId从小到大排序。freq
表示lead
链表中迭代器的数量。
1 源码分析
1.1 tail 是小顶堆
tail是个小顶堆,删除元素只在堆顶进行,添加元素只在堆的末尾进行,删除元素的函数popTail
:
private DisiWrapper popTail() {
final DisiWrapper result = tail[0]; // 被删除的堆顶元素
tail[0] = tail[--tailSize]; // 从堆尾取出一个元素放到堆顶,这个时候堆是不平衡的
downHeapCost(tail, tailSize); // 从堆顶往下调整堆
return result;
}
从堆顶往下调整,将cost最小的迭代器不断往上推,downHeapCost
函数如下:
private static void downHeapCost(DisiWrapper[] heap, int size) {
int i = 0;
final DisiWrapper node = heap[0]; // 记录整个堆的 root节点
int j = leftNode(i);
if (j < size) {
// 判断当前的 root节点是否是叶子节点
int k = rightNode(j);
if (k < size && heap[k].cost < heap[j].cost) {
// 如果当前节点有左右子节点,那么选出子节点中cost最小的那个,记录到 j
j = k;
}
// 判断当前 root节点是否比左右子节点中cost最小的那个还要小
// 如果是,则将最小的那个节点推到 root节点
if (heap[j].cost < node.cost) {
do {
// 将cost较小的节点推到 root节点
heap[i] = heap[j];
// 将 root节点设置为较cost小的节点
i = j;
j =