ant_quic/bootstrap_cache/
config.rs1use std::path::PathBuf;
11use std::time::Duration;
12
13#[derive(Debug, Clone)]
15pub struct BootstrapCacheConfig {
16 pub cache_dir: PathBuf,
18
19 pub max_peers: usize,
21
22 pub epsilon: f64,
25
26 pub stale_threshold: Duration,
28
29 pub save_interval: Duration,
31
32 pub quality_update_interval: Duration,
34
35 pub cleanup_interval: Duration,
37
38 pub min_peers_to_save: usize,
40
41 pub enable_file_locking: bool,
43
44 pub weights: QualityWeights,
46}
47
48#[derive(Debug, Clone)]
50pub struct QualityWeights {
51 pub success_rate: f64,
53 pub rtt: f64,
55 pub freshness: f64,
57 pub capabilities: f64,
59}
60
61impl Default for BootstrapCacheConfig {
62 fn default() -> Self {
63 Self {
64 cache_dir: default_cache_dir(),
65 max_peers: 30_000,
66 epsilon: 0.1,
67 stale_threshold: Duration::from_secs(7 * 24 * 3600), save_interval: Duration::from_secs(5 * 60), quality_update_interval: Duration::from_secs(3600), cleanup_interval: Duration::from_secs(6 * 3600), min_peers_to_save: 10,
72 enable_file_locking: true,
73 weights: QualityWeights::default(),
74 }
75 }
76}
77
78impl Default for QualityWeights {
79 fn default() -> Self {
80 Self {
81 success_rate: 0.4,
82 rtt: 0.25,
83 freshness: 0.15,
84 capabilities: 0.2,
85 }
86 }
87}
88
89impl BootstrapCacheConfig {
90 pub fn builder() -> BootstrapCacheConfigBuilder {
92 BootstrapCacheConfigBuilder::default()
93 }
94}
95
96#[derive(Default)]
98pub struct BootstrapCacheConfigBuilder {
99 config: BootstrapCacheConfig,
100}
101
102impl BootstrapCacheConfigBuilder {
103 pub fn cache_dir(mut self, dir: impl Into<PathBuf>) -> Self {
105 self.config.cache_dir = dir.into();
106 self
107 }
108
109 pub fn max_peers(mut self, max: usize) -> Self {
111 self.config.max_peers = max;
112 self
113 }
114
115 pub fn epsilon(mut self, epsilon: f64) -> Self {
117 self.config.epsilon = epsilon.clamp(0.0, 1.0);
118 self
119 }
120
121 pub fn stale_threshold(mut self, duration: Duration) -> Self {
123 self.config.stale_threshold = duration;
124 self
125 }
126
127 pub fn save_interval(mut self, duration: Duration) -> Self {
129 self.config.save_interval = duration;
130 self
131 }
132
133 pub fn quality_update_interval(mut self, duration: Duration) -> Self {
135 self.config.quality_update_interval = duration;
136 self
137 }
138
139 pub fn cleanup_interval(mut self, duration: Duration) -> Self {
141 self.config.cleanup_interval = duration;
142 self
143 }
144
145 pub fn min_peers_to_save(mut self, min: usize) -> Self {
147 self.config.min_peers_to_save = min;
148 self
149 }
150
151 pub fn enable_file_locking(mut self, enable: bool) -> Self {
153 self.config.enable_file_locking = enable;
154 self
155 }
156
157 pub fn weights(mut self, weights: QualityWeights) -> Self {
159 self.config.weights = weights;
160 self
161 }
162
163 pub fn build(self) -> BootstrapCacheConfig {
165 self.config
166 }
167}
168
169fn default_cache_dir() -> PathBuf {
170 if let Ok(tmpdir) = std::env::var("TMPDIR") {
172 return PathBuf::from(tmpdir).join("ant-quic-cache");
173 }
174
175 if let Some(cache_dir) = dirs::cache_dir() {
177 cache_dir.join("ant-quic")
178 } else if let Some(home) = dirs::home_dir() {
179 home.join(".cache").join("ant-quic")
180 } else {
181 PathBuf::from(".ant-quic-cache")
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188
189 #[test]
190 fn test_default_config() {
191 let config = BootstrapCacheConfig::default();
192 assert_eq!(config.max_peers, 30_000);
193 assert!((config.epsilon - 0.1).abs() < f64::EPSILON);
194 assert_eq!(config.stale_threshold, Duration::from_secs(7 * 24 * 3600));
195 }
196
197 #[test]
198 fn test_builder() {
199 let config = BootstrapCacheConfig::builder()
200 .max_peers(10_000)
201 .epsilon(0.2)
202 .cache_dir("/tmp/test")
203 .build();
204
205 assert_eq!(config.max_peers, 10_000);
206 assert!((config.epsilon - 0.2).abs() < f64::EPSILON);
207 assert_eq!(config.cache_dir, PathBuf::from("/tmp/test"));
208 }
209
210 #[test]
211 fn test_epsilon_clamping() {
212 let config = BootstrapCacheConfig::builder().epsilon(1.5).build();
213 assert!((config.epsilon - 1.0).abs() < f64::EPSILON);
214
215 let config = BootstrapCacheConfig::builder().epsilon(-0.5).build();
216 assert!(config.epsilon.abs() < f64::EPSILON);
217 }
218}