use std::collections::HashMap;
use crate::{
StateMap,
statemap::{StateMapKey, StateMapValue},
};
#[derive(Debug, Clone)]
pub struct Diff<K, T> {
diff: Vec<(K, T)>,
is_full: bool,
from_update_id: u64,
upto_update_id: u64,
}
impl<K, T> Diff<K, T> {
pub fn new<I>(diff: I, is_full: bool, from_update_id: u64, upto_update_id: u64) -> Self
where
I: IntoIterator<Item = (K, T)>,
{
Self {
diff: diff.into_iter().collect(),
is_full,
from_update_id,
upto_update_id,
}
}
pub fn empty() -> Diff<K, T> {
Self {
diff: Vec::new(),
is_full: false,
from_update_id: 0,
upto_update_id: 0,
}
}
pub fn get_diff(&self) -> &Vec<(K, T)> {
&self.diff
}
pub fn is_full_update(&self) -> bool {
self.is_full
}
pub fn from_update_id(&self) -> u64 {
self.from_update_id
}
pub fn upto_update_id(&self) -> u64 {
self.upto_update_id
}
pub fn is_empty(&self) -> bool {
self.diff.is_empty()
}
}
impl<K: StateMapKey, T: StateMapValue> Diff<K, T> {
pub fn compress(self) -> Self {
let mut new_diff = Self {
diff: Vec::new(),
is_full: self.is_full,
from_update_id: self.from_update_id,
upto_update_id: self.upto_update_id,
};
let mut diff_hashmap = HashMap::new();
for (k, v) in self.diff {
diff_hashmap.insert(k, v);
}
new_diff.diff.reserve_exact(diff_hashmap.len());
for (k, v) in diff_hashmap {
new_diff.diff.push((k, v));
}
new_diff
}
pub fn merge<I>(iterator: I) -> Diff<K, T>
where
I: IntoIterator<Item = Diff<K, T>>,
{
let mut total_diff = HashMap::new();
let mut min_update_id = u64::MAX;
let mut max_update_id = u64::MIN;
iterator.into_iter().for_each(|x| {
min_update_id = min_update_id.min(x.from_update_id);
max_update_id = max_update_id.max(x.upto_update_id);
x.diff.into_iter().for_each(|x| {
total_diff.insert(x.0, x.1);
});
});
Diff::new(total_diff, false, min_update_id, max_update_id)
}
pub fn full_diff(statemap: &StateMap<K, T>) -> Self {
Diff::new(
statemap
.into_iter()
.map(|(k, v)| (k.to_owned(), v.to_owned())),
true,
0,
statemap.get_update_id(),
)
}
}