use std::sync::Arc;
use crate::segment::{SegmentReader, chunk_map::ChunkMap};
use super::{DocBitset, Query, Scorer, ScorerOptions};
pub(super) fn physical_results(
hits: &mut [super::ScoredDoc],
reader: &SegmentReader,
field: Option<crate::Field>,
) {
if let Some(map) = field.and_then(|field| reader.chunk_map(field)) {
for hit in hits {
hit.doc_id = map
.document_slot(hit.doc_id)
.expect("validated document map");
}
}
}
pub(super) fn prepare<'a>(
reader: &'a SegmentReader,
query: &dyn Query,
options: &mut ScorerOptions,
complete: bool,
) -> Option<&'a ChunkMap> {
let field = query.physical_text_field(reader, complete || options.collect_positions)?;
let map = reader.chunk_map(field)?;
if !map.is_document_map() {
return None;
}
options.physical_text_field = Some(field);
options.complete_text_matches |= complete;
options.eligibility = None;
Some(map)
}
pub(super) fn filtered<'a>(
scorer: Box<dyn Scorer + 'a>,
alive: Option<Arc<DocBitset>>,
map: Option<&'a ChunkMap>,
) -> Box<dyn Scorer + 'a> {
if let (Some(map), Some(bits)) = (map, alive.as_ref()) {
let bits = bits.clone();
Box::new(super::PredicatedScorer::new(
scorer,
vec![Box::new(move |slot| bits.contains(map.doc_id(slot)))],
Vec::new(),
Vec::new(),
))
} else {
super::filtered::filtered(scorer, alive)
}
}