pub struct CounterDiff {
pub max_value: u64,
previous_value: Option<u64>,
}
pub enum CounterDiffUpdate {
FirstTime,
Difference(u64),
CorrectedDifference(u64),
}
impl CounterDiff {
pub fn with_max_value(max_value: u64) -> CounterDiff {
CounterDiff {
max_value,
previous_value: None,
}
}
pub fn update(&mut self, new_value: u64) -> CounterDiffUpdate {
debug_assert!(new_value <= self.max_value, "No value can be greater than max_value!");
let res = match self.previous_value {
Some(prev) => {
if new_value < prev {
let diff = new_value - prev + self.max_value;
CounterDiffUpdate::CorrectedDifference(diff)
} else {
let diff = new_value - prev;
CounterDiffUpdate::Difference(diff)
}
}
None => CounterDiffUpdate::FirstTime,
};
self.previous_value = Some(new_value);
res
}
}
impl CounterDiffUpdate {
pub fn difference(self) -> Option<u64> {
match self {
CounterDiffUpdate::FirstTime => None,
CounterDiffUpdate::Difference(d) | CounterDiffUpdate::CorrectedDifference(d) => Some(d),
}
}
}
impl From<CounterDiffUpdate> for Option<u64> {
fn from(diff: CounterDiffUpdate) -> Self {
diff.difference()
}
}