use crate::*;
use serde::{Deserialize, Serialize};
use std::collections::hash_map::{self, HashMap};
use std::fmt;
use std::iter::FromIterator;
pub type VClock<A> = Clock<A, MaxSet>;
pub type AEClock<A> = Clock<A, AboveExSet>;
pub type ARClock<A> = Clock<A, AboveRangeSet>;
pub type BEClock<A> = Clock<A, BelowExSet>;
#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct Clock<A: Actor, E: EventSet> {
clock: HashMap<A, E>,
}
impl<A: Actor, E: EventSet> Clock<A, E> {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
Clock {
clock: HashMap::new(),
}
}
pub fn with<I: IntoIterator<Item = A>>(iter: I) -> Self {
Clock {
clock: iter.into_iter().map(|actor| (actor, E::new())).collect(),
}
}
pub fn from<I: IntoIterator<Item = (A, E)>>(iter: I) -> Self {
Clock {
clock: HashMap::from_iter(iter),
}
}
pub fn len(&self) -> usize {
self.clock.len()
}
pub fn is_empty(&self) -> bool {
self.clock.is_empty()
}
pub fn next(&mut self, actor: &A) -> u64 {
self.upsert(actor, |eset| eset.next_event(), || (E::from_event(1), 1))
}
fn upsert<F, D, R>(&mut self, actor: &A, mut map: F, default: D) -> R
where
F: FnMut(&mut E) -> R,
D: FnOnce() -> (E, R),
{
match self.clock.get_mut(actor) {
Some(eset) => map(eset),
None => {
let (value, result) = default();
self.clock.insert(actor.clone(), value);
result
}
}
}
pub fn get(&self, actor: &A) -> Option<&E> {
self.clock.get(actor)
}
pub fn get_mut(&mut self, actor: &A) -> Option<&mut E> {
self.clock.get_mut(actor)
}
pub fn add(&mut self, actor: &A, seq: u64) -> bool {
self.upsert(
actor,
|eset| eset.add_event(seq),
|| (E::from_event(seq), true),
)
}
pub fn add_range(&mut self, actor: &A, start: u64, end: u64) -> bool {
self.upsert(
actor,
|eset| eset.add_event_range(start, end),
|| (E::from_event_range(start, end), true),
)
}
pub fn contains(&self, actor: &A, seq: u64) -> bool {
self.clock
.get(actor)
.map_or(false, |eset| eset.is_event(seq))
}
pub fn frontier(&self) -> VClock<A> {
let frontier = self.clock.iter().map(|(actor, eset)| {
(actor.clone(), MaxSet::from(eset.frontier()))
});
VClock::from(frontier)
}
pub fn frontier_threshold(&self, threshold: usize) -> Option<u64> {
debug_assert!(threshold > 0);
let clock_size = self.clock.len();
if threshold <= clock_size {
let mut frontiers: Vec<_> =
self.clock.iter().map(|(_, eset)| eset.frontier()).collect();
frontiers.sort_unstable();
frontiers.into_iter().nth(clock_size - threshold)
} else {
None
}
}
pub fn join(&mut self, other: &Self) {
for (actor, eset) in other.clock.iter() {
self.upsert(
actor,
|current_eset| current_eset.join(eset),
|| (eset.clone(), ()),
);
}
}
pub fn meet(&mut self, other: &Self) {
let mut to_remove = Vec::new();
for (actor, eset) in self.clock.iter_mut() {
if let Some(other_eset) = other.get(actor) {
eset.meet(other_eset);
} else {
to_remove.push(actor.clone());
}
}
for actor in to_remove {
self.clock.remove(&actor);
}
}
pub fn iter<'a>(&self) -> Iter<'_, A, E> {
Iter(self.clock.iter())
}
pub fn iter_mut<'a>(&mut self) -> IterMut<'_, A, E> {
IterMut(self.clock.iter_mut())
}
pub fn subtracted(&self, other: &Self) -> HashMap<A, Vec<u64>> {
self.clock
.iter()
.map(|(actor, eset)| {
let subtracted = if let Some(other_eset) = other.get(actor) {
eset.subtracted(other_eset)
} else {
eset.clone().event_iter().collect()
};
(actor.clone(), subtracted)
})
.collect()
}
}
pub fn vclock_from_seqs<I: IntoIterator<Item = u64>>(iter: I) -> VClock<u64> {
Clock::from(
iter.into_iter()
.enumerate()
.map(|(actor, seq)| (actor as u64, MaxSet::from_event(seq))),
)
}
pub struct IntoIter<A: Actor, E: EventSet>(hash_map::IntoIter<A, E>);
impl<A: Actor, E: EventSet> Iterator for IntoIter<A, E> {
type Item = (A, E);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<A: Actor, E: EventSet> IntoIterator for Clock<A, E> {
type Item = (A, E);
type IntoIter = IntoIter<A, E>;
fn into_iter(self) -> Self::IntoIter {
IntoIter(self.clock.into_iter())
}
}
pub struct Iter<'a, A: Actor, E: EventSet>(hash_map::Iter<'a, A, E>);
impl<'a, A: Actor, E: EventSet> Iterator for Iter<'a, A, E> {
type Item = (&'a A, &'a E);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct IterMut<'a, A: Actor, E: EventSet>(hash_map::IterMut<'a, A, E>);
impl<'a, A: Actor, E: EventSet> Iterator for IterMut<'a, A, E> {
type Item = (&'a A, &'a mut E);
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<A: Actor, E: EventSet> fmt::Debug for Clock<A, E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let clock: std::collections::BTreeMap<_, _> =
self.clock.iter().collect();
write!(f, "{:?}", clock)
}
}