Skip to main content

post_cortex_embeddings/vector_db/
config.rs

1// Copyright (c) 2025, 2026 Julius ML
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12
13//! Vector database configuration and search quality presets.
14
15use std::path::PathBuf;
16
17/// Search mode for vector similarity search
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
19pub enum SearchMode {
20    /// Exact search using full linear scan - highest accuracy, slowest
21    Exact,
22    /// Approximate search using HNSW - fastest, good accuracy
23    Approximate,
24    /// Balanced search with optimized HNSW parameters - good speed/accuracy tradeoff
25    #[default]
26    Balanced,
27}
28
29/// Search quality preset for automatic parameter tuning
30#[derive(Debug, Clone, Copy)]
31pub enum SearchQualityPreset {
32    /// Fast search with lower accuracy (ef_search = 32)
33    Fast,
34    /// Balanced search (ef_search = 64)
35    Balanced,
36    /// Accurate search with higher recall (ef_search = 128)
37    Accurate,
38    /// Maximum accuracy search (ef_search = 256)
39    Maximum,
40}
41
42impl SearchQualityPreset {
43    /// Get ef_search value for this preset
44    pub fn ef_search(&self) -> usize {
45        match self {
46            SearchQualityPreset::Fast => 32,
47            SearchQualityPreset::Balanced => 64,
48            SearchQualityPreset::Accurate => 128,
49            SearchQualityPreset::Maximum => 256,
50        }
51    }
52}
53
54/// Configuration for the vector database
55#[derive(Debug, Clone)]
56pub struct VectorDbConfig {
57    /// Vector dimension (must match embedding model)
58    pub dimension: usize,
59    /// Maximum number of connections per node in HNSW
60    pub max_connections: usize,
61    /// Size of the dynamic candidate list
62    pub ef_construction: usize,
63    /// Size of the search candidate list
64    pub ef_search: usize,
65    /// Number of layers in HNSW hierarchy
66    pub num_layers: usize,
67    /// Enable vector quantization for memory optimization
68    pub enable_quantization: bool,
69    /// Quantization buckets (power of 2)
70    pub quantization_buckets: usize,
71    /// Enable HNSW indexing
72    pub enable_hnsw_index: bool,
73    /// Up to this many vectors, searches are exact linear scans and no HNSW
74    /// graph is maintained (inserts stay O(1)). The first insert that
75    /// crosses it builds the graph once; from then on it is kept up to date
76    /// incrementally. [`VectorDB::build_index`](super::VectorDB::build_index)
77    /// builds it explicitly regardless of size.
78    pub exact_search_threshold: usize,
79    /// Distance threshold for considering vectors similar
80    pub distance_threshold: f32,
81    /// Maximum number of vectors to store in total (all sources). Inserts
82    /// beyond it fail with an error; bulk inserts stop and warn.
83    pub max_vectors: usize,
84    /// Auto-save interval (number of operations)
85    pub auto_save_interval: usize,
86    /// Enable persistent storage
87    pub persistent_storage: bool,
88    /// Storage path
89    pub storage_path: Option<PathBuf>,
90    /// Enable Product Quantization for memory optimization
91    pub enable_product_quantization: bool,
92    /// Number of subvectors for PQ (must divide dimension evenly)
93    pub pq_subvectors: usize,
94    /// Bits per PQ code (2^bits centroids per subvector)
95    pub pq_bits: usize,
96    /// Keep in-memory BM25 postings over the vectors' text
97    /// ([`VectorDB::search_text`](super::VectorDB::search_text)), for storage
98    /// backends without full-text search of their own. Word frequencies for
99    /// [`VectorDB::query_terms`](super::VectorDB::query_terms) are kept
100    /// regardless.
101    pub full_text_index: bool,
102}
103
104impl Default for VectorDbConfig {
105    fn default() -> Self {
106        Self {
107            dimension: 384, // Default for MiniLM model
108            max_connections: 16,
109            ef_construction: 200,
110            ef_search: 50,
111            num_layers: 4,
112            // Off: the u8 copy is never read by search; keep it opt-in.
113            enable_quantization: false,
114            quantization_buckets: 256,
115            enable_hnsw_index: true,
116            exact_search_threshold: 10_000,
117            distance_threshold: 0.7,
118            max_vectors: 100_000,
119            auto_save_interval: 1000,
120            persistent_storage: false,
121            storage_path: None,
122            enable_product_quantization: false, // Disabled by default (experimental)
123            pq_subvectors: 8,                   // 384/8 = 48 dims per subvector
124            pq_bits: 8,                         // 256 centroids per subvector
125            full_text_index: false,
126        }
127    }
128}