hermes_core/query/vector/
binary_dense.rs1use crate::dsl::Field;
4use crate::segment::SegmentReader;
5use std::sync::{Arc, Mutex};
6
7use super::VectorResultScorer;
8use super::combiner::MultiValueCombiner;
9use crate::query::traits::{CountFuture, Query, Scorer, ScorerFuture};
10
11#[derive(Debug, Clone)]
16pub struct BinaryDenseVectorQuery {
17 pub field: Field,
19 pub vector: Vec<u8>,
21 pub combiner: MultiValueCombiner,
23 probe_cache: Arc<Mutex<Option<crate::structures::IvfProbePlan>>>,
24 shared_vector: std::sync::OnceLock<Arc<[u8]>>,
28}
29
30impl std::fmt::Display for BinaryDenseVectorQuery {
31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32 write!(
33 f,
34 "BinaryDense({}, bytes={})",
35 self.field.0,
36 self.vector.len(),
37 )
38 }
39}
40
41impl BinaryDenseVectorQuery {
42 pub fn new(field: Field, vector: Vec<u8>) -> Self {
43 Self {
44 field,
45 vector,
46 combiner: MultiValueCombiner::Max,
47 probe_cache: Arc::new(Mutex::new(None)),
48 shared_vector: std::sync::OnceLock::new(),
49 }
50 }
51
52 fn shared_vector(&self) -> Arc<[u8]> {
55 let shared = self
56 .shared_vector
57 .get_or_init(|| Arc::from(self.vector.as_slice()));
58 if shared.as_ref() == self.vector.as_slice() {
59 Arc::clone(shared)
60 } else {
61 Arc::from(self.vector.as_slice())
62 }
63 }
64
65 pub fn with_combiner(mut self, combiner: MultiValueCombiner) -> Self {
66 self.combiner = combiner;
67 self
68 }
69}
70
71impl Query for BinaryDenseVectorQuery {
72 fn scorer<'a>(&self, reader: &'a SegmentReader, limit: usize) -> ScorerFuture<'a> {
73 let field = self.field;
74 let vector = self.shared_vector();
75 let combiner = self.combiner;
76 let probe_cache = Arc::clone(&self.probe_cache);
77 Box::pin(async move {
78 let results = reader
79 .search_binary_dense_vector_with_probe_cache(
80 field,
81 &vector,
82 limit,
83 combiner,
84 &probe_cache,
85 )
86 .await?;
87
88 Ok(Box::new(VectorResultScorer::new(results, field.0)) as Box<dyn Scorer>)
89 })
90 }
91
92 #[cfg(feature = "sync")]
93 fn scorer_sync<'a>(
94 &self,
95 reader: &'a SegmentReader,
96 limit: usize,
97 ) -> crate::Result<Box<dyn Scorer + 'a>> {
98 let results = reader.search_binary_dense_vector_sync_with_probe_cache(
99 self.field,
100 &self.vector,
101 limit,
102 self.combiner,
103 &self.probe_cache,
104 )?;
105 Ok(Box::new(VectorResultScorer::new(results, self.field.0)) as Box<dyn Scorer>)
106 }
107
108 fn count_estimate<'a>(&self, _reader: &'a SegmentReader) -> CountFuture<'a> {
109 Box::pin(async move { Ok(u32::MAX) })
110 }
111}