extern crate alloc;
use alloc::collections::{BTreeMap, BTreeSet};
use crate::metis::{Dot, DotSet};
use super::super::DotStore;
use super::DotMap;
impl<K: Ord + Clone, S: DotStore> DotStore for DotMap<K, S> {
fn dots(&self) -> impl Iterator<Item = Dot> + '_ {
self.entries.values().flat_map(DotStore::dots)
}
fn is_bottom(&self) -> bool {
self.entries.is_empty()
}
fn causal_merge(&self, self_context: &DotSet, other: &Self, other_context: &DotSet) -> Self {
let bottom = S::default();
let mut entries = BTreeMap::new();
for (key, mine) in &self.entries {
let theirs = other.entries.get(key).unwrap_or(&bottom);
let joined = mine.causal_merge(self_context, theirs, other_context);
if !joined.is_bottom() {
let _ = entries.insert(key.clone(), joined);
}
}
for (key, theirs) in &other.entries {
if self.entries.contains_key(key) {
continue;
}
let joined = bottom.causal_merge(self_context, theirs, other_context);
if !joined.is_bottom() {
let _ = entries.insert(key.clone(), joined);
}
}
Self { entries }
}
fn restrict(&self, roster: impl IntoIterator<Item = u32>) -> Self {
let roster: BTreeSet<u32> = roster.into_iter().collect();
let entries = self
.entries
.iter()
.filter_map(|(key, store)| {
let kept = store.restrict(roster.iter().copied());
(!kept.is_bottom()).then(|| (key.clone(), kept))
})
.collect();
Self { entries }
}
fn novel_to(&self, context: &DotSet) -> Self {
let entries = self
.entries
.iter()
.filter_map(|(key, store)| {
let novel = store.novel_to(context);
(!novel.is_bottom()).then(|| (key.clone(), novel))
})
.collect();
Self { entries }
}
fn novel_to_witnessed(&self, context: &DotSet, recording: &DotSet) -> Self {
let entries = self
.entries
.iter()
.filter_map(|(key, store)| {
let novel = store.novel_to_witnessed(context, recording);
(!novel.is_bottom()).then(|| (key.clone(), novel))
})
.collect();
Self { entries }
}
}