pub struct BlockImpact {
pub max_tf: u32,
pub min_len: u16,
}Expand description
One block’s impact pair: the two extremes that bound every posting in it.
§Why a pair and not a stored score
A stored score is a number computed under one set of statistics. BM25’s
score / ceiling is tf / (tf + k1 * (1 - b + b * len / avgdl)), so
idf cancels but avgdl and (k1, b) do not: a bound sealed when
documents were short falls below a true score once avgdl rises, and a
bound sealed under beir() falls below one read under anserini().
Measured shortfalls were 15.21% and 19.56%.
A pair carries no statistics at all. term_score is monotone increasing
in tf and monotone decreasing in len, so evaluating it at the block’s
largest tf and shortest document dominates every posting in the block
under ANY statistics and ANY (k1, b). The two extremes need not come
from the same document; pairing them is looser than the true maximum and
is therefore still an upper bound.
Fields§
§max_tf: u32Largest term frequency in the block.
min_len: u16Smallest document length in the block, saturating DOWN.
Implementations§
Source§impl BlockImpact
impl BlockImpact
Sourcepub const fn from_meta(meta: &BlockMeta) -> Self
pub const fn from_meta(meta: &BlockMeta) -> Self
Reads the pair out of a persisted metadata row.
Sourcepub const fn is_absent(&self) -> bool
pub const fn is_absent(&self) -> bool
Returns true when the pair bounds nothing.
A real block has at least one posting, whose term frequency is at
least one, so a zero max_tf can only mean the pair was never
written — a version 1 stream, or a v2 stream missing an entry.
Sourcepub fn bound(&self, scorer: &TermScorer) -> f64
pub fn bound(&self, scorer: &TermScorer) -> f64
Evaluates the bound under the caller’s live scoring constants.
This is the whole remedy: the bound is computed HERE, at query time, from statistics that are current and parameters the caller chose.