mycroft_support/
aggregator.rs1use std::hash::Hash;
3use std::rc::Rc;
4use std::marker::PhantomData;
5use storage;
6
7pub trait Aggregator {
10 fn aggregate(&self, &[usize]) -> usize;
13 fn agg_clone(&self) -> Box<Aggregator>;
15}
16
17#[derive(Clone)]
19pub struct Func<F, T> {
20 f: Rc<F>,
21 phantom: PhantomData<T>,
22}
23
24impl<T, F: Fn(&[T]) -> T> Func<F, T> {
25 pub fn new(f: F) -> Self {
27 Self {
28 f: Rc::new(f),
29 phantom: PhantomData,
30 }
31 }
32}
33
34macro_rules! castable_aggregator {
35 ($ty:ty) => {
36impl<F: Fn(&[$ty]) -> $ty + 'static> Aggregator for Func<F, $ty> {
37 fn aggregate(&self, big_ks: &[usize]) -> usize {
38 let ks: Vec<_> = big_ks.iter().map(|x| *x as $ty).collect();
39 (self.f)(&ks) as usize
40 }
41 fn agg_clone(&self) -> Box<Aggregator> {
42 Box::new(Self { f: self.f.clone(), phantom: PhantomData})
43 }
44}
45}
46}
47
48impl<F: Fn(&[bool]) -> bool + 'static> Aggregator for Func<F, bool> {
49 fn aggregate(&self, big_ks: &[usize]) -> usize {
50 let ks: Vec<_> = big_ks.iter().map(|x| *x == 1).collect();
51 (self.f)(&ks) as usize
52 }
53 fn agg_clone(&self) -> Box<Aggregator> {
54 Box::new(Self {
55 f: self.f.clone(),
56 phantom: PhantomData,
57 })
58 }
59}
60
61castable_aggregator!(u8);
62castable_aggregator!(u16);
63castable_aggregator!(u32);
64castable_aggregator!(u64);
65castable_aggregator!(usize);
66castable_aggregator!(i8);
67castable_aggregator!(i16);
68castable_aggregator!(i32);
69castable_aggregator!(i64);
70castable_aggregator!(isize);
71
72#[derive(Clone)]
75pub struct FuncData<T, F> {
76 f: Rc<F>,
77 data: storage::Data<T>,
78}
79
80impl<T, F: Fn(&[&T]) -> T> FuncData<T, F> {
81 pub fn new(f: F, data: storage::Data<T>) -> Self {
84 Self {
85 f: Rc::new(f),
86 data: data,
87 }
88 }
89}
90
91impl<T: Hash + PartialEq + 'static, F: Fn(&[&T]) -> T + 'static> Aggregator for FuncData<T, F> {
92 fn aggregate(&self, ks: &[usize]) -> usize {
93 let v = {
94 let vs: Vec<_> = ks.iter().map(|k| &self.data[*k]).collect();
95 (self.f)(&vs)
96 };
97 unsafe {
98 self.data.read_exit(ks.len());
99 }
100 self.data.insert(v)
101 }
102 fn agg_clone(&self) -> Box<Aggregator> {
103 Box::new(Self {
104 f: self.f.clone(),
105 data: self.data.clone(),
106 })
107 }
108}