use crate::core::{DocId, Result, ScoreMode, Scorer, TwoPhaseIterator};
use crate::query::{BoundQuery, Query, ScorerSupplier};
use crate::search::searcher::Searcher;
use crate::segment::reader::SegmentReader;
pub struct ConstantScoreQuery {
pub(crate) inner: Box<dyn Query>,
pub boost: f32,
}
impl Query for ConstantScoreQuery {
fn bind(&self, searcher: &Searcher, _score_mode: ScoreMode) -> Result<Box<dyn BoundQuery>> {
let inner_weight = self.inner.bind(searcher, ScoreMode::CompleteNoScores)?;
Ok(Box::new(BoundConstantScoreQuery {
inner: inner_weight,
boost: self.boost,
}))
}
}
struct BoundConstantScoreQuery {
inner: Box<dyn BoundQuery>,
boost: f32,
}
impl BoundQuery for BoundConstantScoreQuery {
fn scorer_supplier(&self, reader: &SegmentReader) -> Result<Option<Box<dyn ScorerSupplier>>> {
match self.inner.scorer_supplier(reader)? {
Some(supplier) => Ok(Some(Box::new(ConstantScoreScorerSupplier {
inner: supplier,
boost: self.boost,
}))),
None => Ok(None),
}
}
}
struct ConstantScoreScorerSupplier {
inner: Box<dyn ScorerSupplier>,
boost: f32,
}
unsafe impl Send for ConstantScoreScorerSupplier {}
impl ScorerSupplier for ConstantScoreScorerSupplier {
fn cost(&self) -> u64 {
self.inner.cost()
}
fn scorer(self: Box<Self>) -> Result<Box<dyn Scorer>> {
let inner = self.inner.scorer()?;
Ok(Box::new(ConstantScoreScorer {
inner,
boost: self.boost,
}))
}
}
struct ConstantScoreScorer {
inner: Box<dyn Scorer>,
boost: f32,
}
impl Scorer for ConstantScoreScorer {
fn doc_id(&self) -> DocId {
self.inner.doc_id()
}
fn next(&mut self) -> DocId {
self.inner.next()
}
fn advance(&mut self, target: DocId) -> DocId {
self.inner.advance(target)
}
fn score(&mut self) -> f32 {
self.boost
}
fn two_phase(&mut self) -> Option<&mut dyn TwoPhaseIterator> {
self.inner.two_phase()
}
}