use super::proximity::{Cosine, Proximity};
use super::merge::{Mean, Merge};
use std::sync::Arc;
#[derive(Clone)]
pub struct ArmsConfig {
pub dimensionality: usize,
pub proximity: Arc<dyn Proximity>,
pub merge: Arc<dyn Merge>,
pub normalize_on_insert: bool,
pub tiers: TierConfig,
}
impl ArmsConfig {
pub fn new(dimensionality: usize) -> Self {
Self {
dimensionality,
proximity: Arc::new(Cosine),
merge: Arc::new(Mean),
normalize_on_insert: true,
tiers: TierConfig::default(),
}
}
pub fn with_proximity<P: Proximity + 'static>(mut self, proximity: P) -> Self {
self.proximity = Arc::new(proximity);
self
}
pub fn with_merge<M: Merge + 'static>(mut self, merge: M) -> Self {
self.merge = Arc::new(merge);
self
}
pub fn with_normalize(mut self, normalize: bool) -> Self {
self.normalize_on_insert = normalize;
self
}
pub fn with_tiers(mut self, tiers: TierConfig) -> Self {
self.tiers = tiers;
self
}
}
impl Default for ArmsConfig {
fn default() -> Self {
Self::new(768)
}
}
#[derive(Clone, Debug)]
pub struct TierConfig {
pub hot_capacity: usize,
pub warm_capacity: usize,
pub promote_after_accesses: u32,
pub evict_after_ms: u64,
}
impl TierConfig {
pub fn new(hot_capacity: usize, warm_capacity: usize) -> Self {
Self {
hot_capacity,
warm_capacity,
promote_after_accesses: 3,
evict_after_ms: 3600 * 1000, }
}
pub fn tiny() -> Self {
Self {
hot_capacity: 1024 * 1024, warm_capacity: 10 * 1024 * 1024, promote_after_accesses: 2,
evict_after_ms: 60 * 1000, }
}
}
impl Default for TierConfig {
fn default() -> Self {
Self {
hot_capacity: 1024 * 1024 * 1024, warm_capacity: 100 * 1024 * 1024 * 1024, promote_after_accesses: 3,
evict_after_ms: 3600 * 1000, }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::proximity::Euclidean;
use crate::core::merge::MaxPool;
#[test]
fn test_default_config() {
let config = ArmsConfig::default();
assert_eq!(config.dimensionality, 768);
assert!(config.normalize_on_insert);
assert_eq!(config.proximity.name(), "cosine");
assert_eq!(config.merge.name(), "mean");
}
#[test]
fn test_custom_config() {
let config = ArmsConfig::new(4096)
.with_proximity(Euclidean)
.with_merge(MaxPool)
.with_normalize(false);
assert_eq!(config.dimensionality, 4096);
assert!(!config.normalize_on_insert);
assert_eq!(config.proximity.name(), "euclidean");
assert_eq!(config.merge.name(), "max_pool");
}
#[test]
fn test_tier_config() {
let tiers = TierConfig::new(1024, 2048);
assert_eq!(tiers.hot_capacity, 1024);
assert_eq!(tiers.warm_capacity, 2048);
}
#[test]
fn test_tier_tiny() {
let tiers = TierConfig::tiny();
assert_eq!(tiers.hot_capacity, 1024 * 1024);
assert_eq!(tiers.evict_after_ms, 60 * 1000);
}
}