1use super::proximity::{Cosine, Proximity};
14use super::merge::{Mean, Merge};
15use std::sync::Arc;
16
17#[derive(Clone)]
21pub struct ArmsConfig {
22 pub dimensionality: usize,
27
28 pub proximity: Arc<dyn Proximity>,
30
31 pub merge: Arc<dyn Merge>,
33
34 pub normalize_on_insert: bool,
36
37 pub tiers: TierConfig,
39}
40
41impl ArmsConfig {
42 pub fn new(dimensionality: usize) -> Self {
46 Self {
47 dimensionality,
48 proximity: Arc::new(Cosine),
49 merge: Arc::new(Mean),
50 normalize_on_insert: true,
51 tiers: TierConfig::default(),
52 }
53 }
54
55 pub fn with_proximity<P: Proximity + 'static>(mut self, proximity: P) -> Self {
57 self.proximity = Arc::new(proximity);
58 self
59 }
60
61 pub fn with_merge<M: Merge + 'static>(mut self, merge: M) -> Self {
63 self.merge = Arc::new(merge);
64 self
65 }
66
67 pub fn with_normalize(mut self, normalize: bool) -> Self {
69 self.normalize_on_insert = normalize;
70 self
71 }
72
73 pub fn with_tiers(mut self, tiers: TierConfig) -> Self {
75 self.tiers = tiers;
76 self
77 }
78}
79
80impl Default for ArmsConfig {
81 fn default() -> Self {
83 Self::new(768)
84 }
85}
86
87#[derive(Clone, Debug)]
89pub struct TierConfig {
90 pub hot_capacity: usize,
92
93 pub warm_capacity: usize,
95
96 pub promote_after_accesses: u32,
98
99 pub evict_after_ms: u64,
101}
102
103impl TierConfig {
104 pub fn new(hot_capacity: usize, warm_capacity: usize) -> Self {
106 Self {
107 hot_capacity,
108 warm_capacity,
109 promote_after_accesses: 3,
110 evict_after_ms: 3600 * 1000, }
112 }
113
114 pub fn tiny() -> Self {
116 Self {
117 hot_capacity: 1024 * 1024, warm_capacity: 10 * 1024 * 1024, promote_after_accesses: 2,
120 evict_after_ms: 60 * 1000, }
122 }
123}
124
125impl Default for TierConfig {
126 fn default() -> Self {
127 Self {
128 hot_capacity: 1024 * 1024 * 1024, warm_capacity: 100 * 1024 * 1024 * 1024, promote_after_accesses: 3,
131 evict_after_ms: 3600 * 1000, }
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::*;
139 use crate::core::proximity::Euclidean;
140 use crate::core::merge::MaxPool;
141
142 #[test]
143 fn test_default_config() {
144 let config = ArmsConfig::default();
145 assert_eq!(config.dimensionality, 768);
146 assert!(config.normalize_on_insert);
147 assert_eq!(config.proximity.name(), "cosine");
148 assert_eq!(config.merge.name(), "mean");
149 }
150
151 #[test]
152 fn test_custom_config() {
153 let config = ArmsConfig::new(4096)
154 .with_proximity(Euclidean)
155 .with_merge(MaxPool)
156 .with_normalize(false);
157
158 assert_eq!(config.dimensionality, 4096);
159 assert!(!config.normalize_on_insert);
160 assert_eq!(config.proximity.name(), "euclidean");
161 assert_eq!(config.merge.name(), "max_pool");
162 }
163
164 #[test]
165 fn test_tier_config() {
166 let tiers = TierConfig::new(1024, 2048);
167 assert_eq!(tiers.hot_capacity, 1024);
168 assert_eq!(tiers.warm_capacity, 2048);
169 }
170
171 #[test]
172 fn test_tier_tiny() {
173 let tiers = TierConfig::tiny();
174 assert_eq!(tiers.hot_capacity, 1024 * 1024);
175 assert_eq!(tiers.evict_after_ms, 60 * 1000);
176 }
177}