contrag_core/vector_store/
mod.rs1pub mod stable_memory_store;
2
3use crate::error::Result;
4use crate::types::{Vector, SearchResult};
5
6#[async_trait::async_trait]
8pub trait VectorStore: Send + Sync {
9 async fn store(&mut self, namespace: &str, vector: Vector) -> Result<()>;
11
12 async fn store_batch(&mut self, namespace: &str, vectors: Vec<Vector>) -> Result<()> {
14 for vector in vectors {
15 self.store(namespace, vector).await?;
16 }
17 Ok(())
18 }
19
20 async fn search(
22 &self,
23 namespace: &str,
24 query_embedding: Vec<f32>,
25 k: usize,
26 ) -> Result<Vec<SearchResult>>;
27
28 async fn delete(&mut self, namespace: &str, vector_id: &str) -> Result<()>;
30
31 async fn delete_namespace(&mut self, namespace: &str) -> Result<()>;
33
34 async fn count(&self, namespace: &str) -> Result<usize>;
36
37 async fn list_namespaces(&self) -> Result<Vec<String>>;
39}
40
41pub fn cosine_similarity(a: &[f32], b: &[f32]) -> f32 {
43 if a.len() != b.len() {
44 return 0.0;
45 }
46
47 let dot_product: f32 = a.iter().zip(b.iter()).map(|(x, y)| x * y).sum();
48 let magnitude_a: f32 = a.iter().map(|x| x * x).sum::<f32>().sqrt();
49 let magnitude_b: f32 = b.iter().map(|x| x * x).sum::<f32>().sqrt();
50
51 if magnitude_a == 0.0 || magnitude_b == 0.0 {
52 return 0.0;
53 }
54
55 dot_product / (magnitude_a * magnitude_b)
56}
57
58pub fn euclidean_distance(a: &[f32], b: &[f32]) -> f32 {
60 if a.len() != b.len() {
61 return f32::MAX;
62 }
63
64 a.iter()
65 .zip(b.iter())
66 .map(|(x, y)| (x - y).powi(2))
67 .sum::<f32>()
68 .sqrt()
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_cosine_similarity() {
77 let a = vec![1.0, 0.0, 0.0];
78 let b = vec![1.0, 0.0, 0.0];
79 assert!((cosine_similarity(&a, &b) - 1.0).abs() < 0.001);
80
81 let c = vec![1.0, 0.0, 0.0];
82 let d = vec![0.0, 1.0, 0.0];
83 assert!((cosine_similarity(&c, &d) - 0.0).abs() < 0.001);
84 }
85
86 #[test]
87 fn test_euclidean_distance() {
88 let a = vec![0.0, 0.0, 0.0];
89 let b = vec![1.0, 0.0, 0.0];
90 assert!((euclidean_distance(&a, &b) - 1.0).abs() < 0.001);
91
92 let c = vec![0.0, 0.0, 0.0];
93 let d = vec![1.0, 1.0, 0.0];
94 assert!((euclidean_distance(&c, &d) - 1.414).abs() < 0.01);
95 }
96}