use crate::core::{MomaRing, OriginStrategy};
use std::marker::PhantomData;
pub struct OriginDrift<S: OriginStrategy> {
ring: MomaRing<S>,
history: Vec<u64>,
_strategy: PhantomData<S>,
}
impl<S: OriginStrategy> OriginDrift<S> {
pub fn new(modulus: u64, strategy: S) -> Self {
Self {
ring: MomaRing::new(modulus, strategy),
history: Vec::new(),
_strategy: PhantomData,
}
}
pub fn next(&mut self, p: u64) -> u64 {
let signature = self.ring.signature(p);
self.history.push(signature);
signature
}
pub fn drift_magnitude(&self) -> f64 {
if self.history.len() < 2 {
return 0.0;
}
let deltas: Vec<f64> = self
.history
.windows(2)
.map(|w| (w[1] as i64 - w[0] as i64).abs() as f64)
.collect();
deltas.iter().sum::<f64>() / deltas.len() as f64
}
pub fn history(&self) -> &[u64] {
&self.history
}
}