Downcast TermScorer for intersection when all legs are TermScorers

This commit is contained in:
Paul Masurel
2018-02-18 10:28:43 +09:00
parent e608e0a1df
commit 5dae6e6bbc
4 changed files with 31 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ error-chain = "0.8"
owning_ref = "0.3"
stable_deref_trait = "1.0.0"
rust-stemmers = "0.1.0"
downcast = "0.9"
[target.'cfg(windows)'.dependencies]
winapi = "0.2"

View File

@@ -167,6 +167,9 @@ extern crate test;
extern crate tinysegmenter;
#[macro_use]
extern crate downcast;
#[cfg(test)]
mod functional_test;

View File

@@ -4,6 +4,9 @@ use postings::{Intersection, Union};
use std::collections::HashMap;
use query::EmptyScorer;
use query::Scorer;
use downcast::Downcast;
use query::term_query::TermScorer;
use std::borrow::Borrow;
use query::Exclude;
use query::Occur;
use query::RequiredOptionalScorer;
@@ -59,8 +62,26 @@ impl BooleanWeight {
if scorers.len() == 1 {
scorers.into_iter().next().unwrap()
} else {
let scorer: Box<Scorer> = box Intersection::from(scorers);
scorer
if scorers
.iter()
.all(|scorer| {
let scorer_ref:&Scorer = scorer.borrow();
Downcast::<TermScorer>::is_type(scorer_ref)
}) {
let scorers: Vec<TermScorer> = scorers.into_iter()
.map(|scorer| {
*Downcast::<TermScorer>::downcast(scorer)
.expect("downcasting should not have failed, we\
checked in advance that the type were correct.")
})
.collect();
let scorer: Box<Scorer> = box Intersection::from(scorers);
scorer
} else {
let scorer: Box<Scorer> = box Intersection::from(scorers);
scorer
}
}
});

View File

@@ -5,11 +5,12 @@ use collector::Collector;
use postings::SkipResult;
use common::BitSet;
use std::ops::DerefMut;
use downcast;
/// Scored set of documents matching a query within a specific segment.
///
/// See [`Query`](./trait.Query.html).
pub trait Scorer: DocSet + 'static {
pub trait Scorer: downcast::Any + DocSet + 'static {
/// Returns the score.
///
/// This method will perform a bit of computation and is not cached.
@@ -24,6 +25,8 @@ pub trait Scorer: DocSet + 'static {
}
}
downcast!(Scorer);
impl<'a> Scorer for Box<Scorer + 'a> {
fn score(&mut self) -> Score {
self.deref_mut().score()