use std::iter::Peekable;
use ::Data;
use collection::{close_under_lub, LeastUpperBound};
use collection::compact::Compact;
use iterators::merge::{Merge, MergeIterator};
use iterators::coalesce::{Coalesce, CoalesceIterator};
pub trait Trace where for<'a> &'a Self: TraceRef<'a, Self::Key, Self::Index, Self::Value> {
type Key: Data;
type Index: LeastUpperBound;
type Value: Data;
fn set_difference(&mut self, time: Self::Index, accumulation: Compact<Self::Key, Self::Value>);
fn trace<'a>(&'a self, key: &Self::Key) -> <&'a Self as TraceRef<'a,Self::Key,Self::Index,Self::Value>>::TIterator {
TraceRef::<'a,Self::Key,Self::Index,Self::Value>::trace(self, key)
}
fn get_difference<'a>(&'a self, key: &Self::Key, time: &Self::Index)
-> Option<<&'a Self as TraceRef<'a,Self::Key,Self::Index,Self::Value>>::VIterator> {
self.trace(key)
.filter(|x| x.0 == time)
.map(|x| x.1)
.next()
}
fn get_collection<'a>(&'a mut self, key: &Self::Key, time: &Self::Index)
-> CollectionIterator<<&'a Self as TraceRef<'a,Self::Key,Self::Index,Self::Value>>::VIterator> {
self.trace(key)
.into_iter()
.filter(|x| x.0 <= time)
.map(|x| x.1)
.merge()
.coalesce()
.peekable()
}
fn interesting_times<'a>(&'a self, key: &Self::Key, time: &Self::Index, stash: &mut Vec<Self::Index>) {
for iter in self.trace(key) {
if !iter.0.le(time) {
let lub = iter.0.least_upper_bound(time);
if !stash.contains(&lub) {
stash.push(lub);
}
}
}
close_under_lub(stash);
}
}
pub trait TraceRef<'a,K,T:'a,V:'a> {
type VIterator: Iterator<Item=(&'a V, i32)>+'a;
type TIterator: Iterator<Item=(&'a T, Self::VIterator)>+'a;
fn trace(self, key: &K) -> Self::TIterator;
}
pub type CollectionIterator<VIterator> = Peekable<CoalesceIterator<MergeIterator<VIterator>>>;