composable_indexes/aggregation/
sum.rs1use num_traits::Num;
2
3use crate::{
4 Index, ShallowClone,
5 core::{Insert, Remove, Seal, Update},
6};
7
8#[derive(Clone)]
10pub struct Sum<T> {
11 sum: T,
12}
13
14impl<T: Num + Copy> Default for Sum<T> {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl<T: Num + Copy> Sum<T> {
21 pub fn new() -> Self {
22 Sum { sum: T::zero() }
23 }
24}
25
26impl<T> Index<T> for Sum<T>
27where
28 T: Num + Copy + 'static,
29{
30 #[inline]
31 fn insert(&mut self, _seal: Seal, op: &Insert<T>) {
32 self.sum = self.sum + *op.new;
33 }
34
35 #[inline]
36 fn remove(&mut self, _seal: Seal, op: &Remove<T>) {
37 self.sum = self.sum - *op.existing;
38 }
39
40 #[inline]
41 fn update(&mut self, _seal: Seal, op: &Update<T>) {
42 self.sum = self.sum - *op.existing + *op.new;
43 }
44}
45
46impl<T: Copy> Sum<T> {
47 #[inline]
48 pub fn get(&self) -> T {
49 self.sum
50 }
51}
52
53impl<T: Clone> ShallowClone for Sum<T> {}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::testutils::prop_assert_reference;
59 use core::num::Wrapping;
60
61 #[test]
62 fn test_sum() {
63 prop_assert_reference(
64 Sum::<Wrapping<i16>>::new,
65 |db| db.query(|ix| ix.get().0),
66 |xs| xs.iter().map(|x| Wrapping(x.0)).sum::<Wrapping<i16>>().0,
67 None,
68 );
69 }
70}