use differential_dataflow::{ExchangeData, VecCollection, Hashable};
use differential_dataflow::difference::{Semigroup, Monoid, Multiply};
use differential_dataflow::operators::arrange::Arranged;
use differential_dataflow::trace::{BatchCursor, BatchDiff, BatchDiffGat, Cursor, Navigable, TraceReader};
pub fn count<'scope, Tr, K, R, F, P>(
prefixes: VecCollection<'scope, Tr::Time, (P, usize, usize), R>,
arrangement: Arranged<'scope, Tr>,
key_selector: F,
index: usize,
) -> VecCollection<'scope, Tr::Time, (P, usize, usize), R>
where
Tr: TraceReader<Batch: Navigable, Time: std::hash::Hash>+Clone+'static,
BatchCursor<Tr>: Cursor<Time = Tr::Time, Diff=isize>,
<BatchCursor<Tr> as Cursor>::KeyContainer: differential_dataflow::trace::implementations::BatchContainer<Owned=K>,
for<'a> BatchDiff<Tr> : Semigroup<BatchDiffGat<'a, Tr>>,
K: Hashable + Ord + Default + 'static,
R: Monoid+Multiply<Output = R>+ExchangeData,
F: Fn(&P)->K+Clone+'static,
P: ExchangeData,
{
crate::operators::lookup_map(
prefixes,
arrangement,
move |p: &(P,usize,usize), k: &mut K| { *k = key_selector(&p.0); },
move |(p,c,i), r, _, s| {
let s = *s as usize;
if *c < s { ((p.clone(), *c, *i), r.clone()) }
else { ((p.clone(), s, index), r.clone()) }
},
Default::default(),
Default::default(),
Default::default(),
)
}