hermes_core/query/
traits.rs1use std::future::Future;
6use std::pin::Pin;
7
8use crate::segment::SegmentReader;
9use crate::{DocId, Result, Score};
10
11#[derive(Debug, Clone, Copy)]
13pub struct Bm25Params {
14 pub k1: f32,
16 pub b: f32,
18}
19
20impl Default for Bm25Params {
21 fn default() -> Self {
22 Self { k1: 1.2, b: 0.75 }
23 }
24}
25
26#[cfg(not(target_arch = "wasm32"))]
28pub type ScorerFuture<'a> = Pin<Box<dyn Future<Output = Result<Box<dyn Scorer + 'a>>> + Send + 'a>>;
29#[cfg(target_arch = "wasm32")]
30pub type ScorerFuture<'a> = Pin<Box<dyn Future<Output = Result<Box<dyn Scorer + 'a>>> + 'a>>;
31
32#[cfg(not(target_arch = "wasm32"))]
34pub type CountFuture<'a> = Pin<Box<dyn Future<Output = Result<u32>> + Send + 'a>>;
35#[cfg(target_arch = "wasm32")]
36pub type CountFuture<'a> = Pin<Box<dyn Future<Output = Result<u32>> + 'a>>;
37
38#[derive(Debug, Clone)]
40pub struct TermQueryInfo {
41 pub field: crate::dsl::Field,
43 pub term: Vec<u8>,
45}
46
47#[derive(Debug, Clone, Copy)]
49pub struct SparseTermQueryInfo {
50 pub field: crate::dsl::Field,
52 pub dim_id: u32,
54 pub weight: f32,
56 pub heap_factor: f32,
58 pub combiner: super::MultiValueCombiner,
60 pub over_fetch_factor: f32,
63}
64
65pub type MatchedPositions = Vec<(u32, Vec<super::ScoredPosition>)>;
68
69macro_rules! define_query_traits {
70 ($($send_bounds:tt)*) => {
71 pub trait Query: std::fmt::Display + $($send_bounds)* {
77 fn scorer<'a>(
85 &self,
86 reader: &'a SegmentReader,
87 limit: usize,
88 ) -> ScorerFuture<'a>;
89
90 fn count_estimate<'a>(&self, reader: &'a SegmentReader) -> CountFuture<'a>;
92
93 #[cfg(feature = "sync")]
98 fn scorer_sync<'a>(
99 &self,
100 reader: &'a SegmentReader,
101 limit: usize,
102 ) -> Result<Box<dyn Scorer + 'a>> {
103 let _ = (reader, limit);
104 Err(crate::error::Error::Query(
105 "sync scorer not supported for this query type".into(),
106 ))
107 }
108
109 fn as_term_query_info(&self) -> Option<TermQueryInfo> {
113 None
114 }
115
116 fn as_sparse_term_query_info(&self) -> Option<SparseTermQueryInfo> {
119 None
120 }
121 }
122
123 pub trait Scorer: super::docset::DocSet + $($send_bounds)* {
125 fn score(&self) -> Score;
127
128 fn matched_positions(&self) -> Option<MatchedPositions> {
131 None
132 }
133 }
134 };
135}
136
137#[cfg(not(target_arch = "wasm32"))]
138define_query_traits!(Send + Sync);
139
140#[cfg(target_arch = "wasm32")]
141define_query_traits!();
142
143impl Query for Box<dyn Query> {
144 fn scorer<'a>(&self, reader: &'a SegmentReader, limit: usize) -> ScorerFuture<'a> {
145 (**self).scorer(reader, limit)
146 }
147
148 fn count_estimate<'a>(&self, reader: &'a SegmentReader) -> CountFuture<'a> {
149 (**self).count_estimate(reader)
150 }
151
152 fn as_term_query_info(&self) -> Option<TermQueryInfo> {
153 (**self).as_term_query_info()
154 }
155
156 fn as_sparse_term_query_info(&self) -> Option<SparseTermQueryInfo> {
157 (**self).as_sparse_term_query_info()
158 }
159
160 #[cfg(feature = "sync")]
161 fn scorer_sync<'a>(
162 &self,
163 reader: &'a SegmentReader,
164 limit: usize,
165 ) -> Result<Box<dyn Scorer + 'a>> {
166 (**self).scorer_sync(reader, limit)
167 }
168}
169
170pub struct EmptyScorer;
172
173impl super::docset::DocSet for EmptyScorer {
174 fn doc(&self) -> DocId {
175 crate::structures::TERMINATED
176 }
177
178 fn advance(&mut self) -> DocId {
179 crate::structures::TERMINATED
180 }
181
182 fn seek(&mut self, _target: DocId) -> DocId {
183 crate::structures::TERMINATED
184 }
185
186 fn size_hint(&self) -> u32 {
187 0
188 }
189}
190
191impl Scorer for EmptyScorer {
192 fn score(&self) -> Score {
193 0.0
194 }
195}