Skip to main content

probabilistic_rs/ebloom/
config.rs

1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3use std::path::PathBuf;
4use std::time::Duration;
5
6use crate::ebloom::error::{EbloomError, Result};
7
8#[derive(Debug, Clone, Builder, Serialize, Deserialize)]
9pub struct ExpiringPersistenceConfig {
10    pub db_path: PathBuf,
11    #[builder(default = "4096")]
12    pub chunk_size_bytes: usize,
13}
14
15#[derive(Debug, Clone, Builder, Serialize, Deserialize)]
16#[builder(setter(into))]
17pub struct ExpiringFilterConfig {
18    #[builder(default = "1_000_000")]
19    pub capacity_per_level: usize,
20    #[builder(default = "0.01")]
21    pub target_fpr: f64,
22    #[builder(default = "Duration::from_secs(60 * 60)")] // 1 hour
23    pub level_duration: Duration,
24    #[builder(default = "3")]
25    pub num_levels: usize,
26    #[builder(default = "None")]
27    pub persistence: Option<ExpiringPersistenceConfig>,
28}
29
30impl ExpiringFilterConfig {
31    pub fn validate(&self) -> Result<()> {
32        if self.capacity_per_level == 0 {
33            return Err(EbloomError::InvalidConfig(
34                "Capacity per level must be greater than 0".to_string(),
35            ));
36        }
37        if self.target_fpr <= 0.0 || self.target_fpr >= 1.0 {
38            return Err(EbloomError::InvalidConfig(
39                "Target false positive rate must be between 0 and 1".to_string(),
40            ));
41        }
42        if self.level_duration.as_millis() == 0 {
43            return Err(EbloomError::InvalidConfig(
44                "Level duration must be greater than 0".to_string(),
45            ));
46        }
47        if self.num_levels == 0 {
48            return Err(EbloomError::InvalidConfig(
49                "Number of levels must be greater than 0".to_string(),
50            ));
51        }
52        if self.num_levels > 255 {
53            return Err(EbloomError::InvalidConfig(
54                "Number of levels must be <= 255".to_string(),
55            ));
56        }
57        Ok(())
58    }
59
60    pub fn to_bytes(&self) -> Result<Vec<u8>> {
61        postcard::to_allocvec(self)
62            .map_err(|e| EbloomError::SerializationError(e.to_string()))
63    }
64
65    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
66        postcard::from_bytes(bytes)
67            .map_err(|e| EbloomError::SerializationError(e.to_string()))
68    }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct LevelMetadata {
73    pub created_at: u64,
74    pub insert_count: u64,
75    pub last_snapshot_at: u64,
76}