use crate::types::{ArchivedInactivityDiff, InactivityDiff};
pub fn diff_inactivity(base: &[u64], target: &[u64]) -> InactivityDiff {
let target_is_zero = target.iter().all(|&v| v == 0);
if target_is_zero {
let base_has_non_zero = base.iter().any(|&v| v != 0);
if base_has_non_zero {
return InactivityDiff::AllZeros(target.len() as u32);
}
}
let common_len = base.len().min(target.len());
let mut indices = Vec::with_capacity(100);
let mut new_values = Vec::with_capacity(100);
for (i, (&v1, &v2)) in base.iter().zip(target.iter()).take(common_len).enumerate() {
if v1 != v2 {
indices.push(i as u32);
new_values.push(v2);
}
}
let extensions = target[common_len..].to_vec();
InactivityDiff::Sparse {
indices,
new_values,
extensions,
}
}
pub fn apply_inactivity(base: &mut Vec<u64>, delta: &ArchivedInactivityDiff) {
match delta {
ArchivedInactivityDiff::AllZeros(len) => {
base.clear();
base.resize(len.to_native() as usize, 0);
}
ArchivedInactivityDiff::Sparse {
indices,
new_values,
extensions,
} => {
for (idx, val) in indices.iter().zip(new_values.iter()) {
let i = (*idx).to_native() as usize;
base[i] = val.to_native();
}
base.reserve(extensions.len());
base.extend(extensions.iter().map(|v| v.to_native()));
}
}
}