use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Tracking {
sizes: Vec<usize>,
}
impl Tracking {
pub fn new(sizes: Vec<usize>) -> Self {
Tracking { sizes }
}
pub fn combine(&mut self, old_id_to_new_id: Vec<usize>, new_size: usize) {
let mut max_other = 0usize;
let mut other_idx = 0usize;
for size in self.sizes.iter_mut() {
loop {
if other_idx >= *size || other_idx >= old_id_to_new_id.len() {
break;
}
let new_id = old_id_to_new_id[other_idx];
if new_id < new_size {
max_other = max_other.max(old_id_to_new_id[other_idx] + 1);
}
other_idx += 1;
}
*size = max_other;
}
}
pub fn get_sizes(&self) -> &[usize] {
&self.sizes
}
}
#[cfg(test)]
mod tests {
use super::*;
fn new_range(size: usize) -> Tracking {
Tracking::new((1..=size).collect())
}
fn new_range_with_zero(size: usize) -> Tracking {
Tracking::new((0..=size).collect())
}
#[test]
fn idempotent() {
let size = 5;
let mut tracking = new_range(size);
let old_id_to_new_id = (0..size).collect();
tracking.combine(old_id_to_new_id, size);
assert_eq!(tracking, new_range(size));
let mut tracking = new_range_with_zero(size);
let old_id_to_new_id = (0..size).collect();
tracking.combine(old_id_to_new_id, size);
assert_eq!(tracking, new_range_with_zero(size));
}
}