use slog::Logger;
use std::fmt::Debug;
pub(crate) trait Dropper: Debug {
fn will_drop(&mut self) -> bool;
}
#[derive(Debug)]
pub(crate) struct ProbabilisticDropper {
logger: Logger,
ratio: f64,
counter: f64,
}
impl ProbabilisticDropper {
pub fn new(logger: Logger, ratio: f64) -> Self {
Self {
logger,
ratio,
counter: 0.0,
}
}
}
impl Dropper for ProbabilisticDropper {
fn will_drop(&mut self) -> bool {
debug!(self.logger, "old counter = {}",self.counter; "ratio" => self.ratio);
self.counter += self.ratio;
debug!(self.logger, "new counter = {}", self.counter; "ratio" => self.ratio);
if self.counter >= 1.0 {
self.counter -= 1.0;
return true;
}
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use slog::Discard;
#[test]
fn probabilistic_dropper_works() {
let logger = Logger::root(Discard, o!());
let ratio = 0.3;
let mut dropper = ProbabilisticDropper::new(logger, ratio);
let n = 10000;
let mut dropped = 0;
for _ in 0..n {
if dropper.will_drop() {
dropped += 1;
}
}
assert!(2900 < dropped);
assert!(dropped < 3100);
}
}