reflex/cache/l2/
config.rs

1use crate::embedding::sinter::SinterConfig;
2use crate::vectordb::bq::{BQ_COLLECTION_NAME, BQ_VECTOR_SIZE, BqConfig};
3
4use super::error::{L2CacheError, L2CacheResult};
5
6/// Default number of candidates fetched from the binary-quantized index.
7pub const DEFAULT_TOP_K_BQ: u64 = 50;
8/// Default number of candidates kept after full-precision rescoring.
9pub const DEFAULT_TOP_K_FINAL: usize = crate::vectordb::rescoring::DEFAULT_TOP_K;
10/// Default collection name used for L2 (binary-quantized collection).
11pub const L2_COLLECTION_NAME: &str = BQ_COLLECTION_NAME;
12/// Default vector size used for L2 (binary-quantized vector size).
13pub const L2_VECTOR_SIZE: u64 = BQ_VECTOR_SIZE;
14
15#[derive(Debug, Clone)]
16/// Configuration for the L2 semantic cache.
17pub struct L2Config {
18    /// Number of BQ candidates to fetch before rescoring.
19    pub top_k_bq: u64,
20    /// Number of candidates to keep after rescoring.
21    pub top_k_final: usize,
22    /// Vector collection name.
23    pub collection_name: String,
24    /// Vector size configured in the backend collection.
25    pub vector_size: u64,
26    /// If true, validate vector dimensions at runtime.
27    pub validate_dimensions: bool,
28    /// Embedding model configuration.
29    pub embedder_config: SinterConfig,
30    /// Binary-quantization backend configuration.
31    pub bq_config: BqConfig,
32}
33
34impl Default for L2Config {
35    fn default() -> Self {
36        Self {
37            top_k_bq: DEFAULT_TOP_K_BQ,
38            top_k_final: DEFAULT_TOP_K_FINAL,
39            collection_name: L2_COLLECTION_NAME.to_string(),
40            vector_size: L2_VECTOR_SIZE,
41            validate_dimensions: true,
42            embedder_config: SinterConfig::default(),
43            bq_config: BqConfig::default(),
44        }
45    }
46}
47
48impl L2Config {
49    /// Creates a config overriding the `top_k_*` settings.
50    pub fn with_top_k(top_k_bq: u64, top_k_final: usize) -> Self {
51        Self {
52            top_k_bq,
53            top_k_final,
54            ..Default::default()
55        }
56    }
57
58    /// Sets the collection name.
59    pub fn collection_name(mut self, name: &str) -> Self {
60        self.collection_name = name.to_string();
61        self
62    }
63
64    /// Sets the embedder config.
65    pub fn embedder_config(mut self, config: SinterConfig) -> Self {
66        self.embedder_config = config;
67        self
68    }
69
70    /// Sets the binary-quantization config.
71    pub fn bq_config(mut self, config: BqConfig) -> Self {
72        self.bq_config = config;
73        self
74    }
75
76    /// Sets the backend vector size.
77    pub fn vector_size(mut self, size: u64) -> Self {
78        self.vector_size = size;
79        self
80    }
81
82    /// Validates basic invariants for the L2 cache.
83    pub fn validate(&self) -> L2CacheResult<()> {
84        if self.top_k_bq == 0 {
85            return Err(L2CacheError::ConfigError {
86                reason: "top_k_bq must be > 0".to_string(),
87            });
88        }
89        if self.top_k_final == 0 {
90            return Err(L2CacheError::ConfigError {
91                reason: "top_k_final must be > 0".to_string(),
92            });
93        }
94        if self.top_k_final as u64 > self.top_k_bq {
95            return Err(L2CacheError::ConfigError {
96                reason: format!(
97                    "top_k_final ({}) cannot be greater than top_k_bq ({})",
98                    self.top_k_final, self.top_k_bq
99                ),
100            });
101        }
102        Ok(())
103    }
104}