|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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); |
|
|
} |
|
|
} |
|
|
|