【lucene】BlockDocsEnum 跟BlockImpactsDocsEnum 的区别
区别集中在 **“如何计算/利用 impacts 并对结果进行提前裁剪”** 这一件事上。
在 Lucene 的代码里,对应的核心方法只有两处,其余接口(nextDoc、advance、docID、freq 等)完全一致,因此:
1. 构造函数
BlockImpactsDocsEnum 在构造时多干了一件事:把 impacts 读出来并缓存
```
BlockImpactsDocsEnum(...){
super(...); // 和 BlockDocsEnum 一样先初始化
readImpacts(); // ← 额外步骤:把 block 内的 impactData 读到内存
}
```
2. advance(int targetDoc)
这是两者真正出现分叉的唯一方法:
- BlockDocsEnum.advance()
只按 doc id 做跳表定位 → 顺序落到 targetDoc 所在的 block → 结束。
- BlockImpactsDocsEnum.advance()
在跳表定位后,还会 **用已缓存的 impacts 做一次上限预估**
→ 如果当前 block 的 maxScore < minCompetitiveScore(全局当前第 N 名的分数),
就继续跳到下一段,**直到找到一个“可能进 Top-N”的 block** 才真正落地,
否则可能直接跳到倒排链末尾,整个子句提前结束。
其余所有 public 方法(nextDoc、docID、freq、cost、positions 等)实现完全相同。
因此:
**差异 = 构造函数里多读的 impacts + advance() 里多做的 score 上限剪枝。**