composable_indexes/aggregation/
generic.rs1use crate::{
2 ShallowClone,
3 core::{Index, Insert, Remove, Seal, Update},
4};
5
6#[derive(Clone)]
28pub struct GenericAggregate<In, Query, State> {
29 current_state: State,
30 query: fn(st: &State) -> Query,
31 insert: fn(&mut State, &In),
32 remove: fn(&mut State, &In),
33}
34
35impl<In, Query, State> GenericAggregate<In, Query, State> {
36 pub fn new(
37 initial_state: State,
38 query: fn(&State) -> Query,
39 insert: fn(&mut State, &In),
40 remove: fn(&mut State, &In),
41 ) -> Self {
42 Self {
43 current_state: initial_state,
44 query,
45 insert,
46 remove,
47 }
48 }
49}
50
51impl<In, Query, State> Index<In> for GenericAggregate<In, Query, State>
52where
53 State: 'static,
54 Query: 'static,
55 In: 'static,
56{
57 #[inline]
58 fn insert(&mut self, _seal: Seal, op: &Insert<In>) {
59 (self.insert)(&mut self.current_state, op.new);
60 }
61
62 #[inline]
63 fn remove(&mut self, _seal: Seal, op: &Remove<In>) {
64 (self.remove)(&mut self.current_state, op.existing);
65 }
66}
67
68impl<In, Query: Clone, State> GenericAggregate<In, Query, State> {
69 #[inline]
70 pub fn get(&self) -> Query {
71 (self.query)(&self.current_state)
72 }
73}
74
75impl<In: Clone, Query: Clone, State: Clone> ShallowClone for GenericAggregate<In, Query, State> {}
76
77pub struct MonoidalAggregate<T, S, O> {
103 state: S,
104 input: fn(&T) -> S,
105 combine: fn(&S, &S) -> S,
106 invert: fn(&S) -> S,
107 output: fn(&S) -> O,
108}
109
110impl<T, S, O> MonoidalAggregate<T, S, O> {
111 pub fn new(
112 empty: S,
113 input: fn(&T) -> S,
114 combine: fn(&S, &S) -> S,
115 invert: fn(&S) -> S,
116 output: fn(&S) -> O,
117 ) -> Self {
118 Self {
119 state: empty,
120 input,
121 combine,
122 invert,
123 output,
124 }
125 }
126
127 pub fn get(&self) -> O {
128 (self.output)(&self.state)
129 }
130}
131
132impl<T, S, O> Index<T> for MonoidalAggregate<T, S, O> {
133 #[inline]
134 fn insert(&mut self, _seal: Seal, op: &Insert<T>) {
135 let inp = (self.input)(op.new);
136 self.state = (self.combine)(&self.state, &inp);
137 }
138
139 #[inline]
140 fn remove(&mut self, _seal: Seal, op: &Remove<T>) {
141 let inp = (self.input)(op.existing);
142 let inv = (self.invert)(&inp);
143 self.state = (self.combine)(&self.state, &inv);
144 }
145
146 #[inline]
147 fn update(&mut self, _seal: Seal, op: &Update<T>) {
148 let old_ = (self.input)(op.existing);
149 let new_ = (self.input)(op.new);
150 let diff = (self.combine)(&(self.invert)(&old_), &new_);
151 self.state = (self.combine)(&self.state, &diff);
152 }
153}
154
155impl<T, S: Clone, O> Clone for MonoidalAggregate<T, S, O> {
156 fn clone(&self) -> Self {
157 MonoidalAggregate {
158 state: self.state.clone(),
159 input: self.input,
160 combine: self.combine,
161 invert: self.invert,
162 output: self.output,
163 }
164 }
165}
166
167impl<T, S: Clone, O> ShallowClone for MonoidalAggregate<T, S, O> {}