fenwick_bit_tree/
fixed_size_tree.rs

1use crate::{FenwickTree, FenwickTreeValue, TreeError, TreeIndex};
2
3pub struct FixedSizeFenwickTree<T: FenwickTreeValue> {
4    data: Vec<T>,
5}
6
7impl<T: FenwickTreeValue> FixedSizeFenwickTree<T> {
8    pub fn new(size: usize) -> Self {
9        Self {
10            data: vec![T::default(); size + 1],
11        }
12    }
13
14    fn size(&self) -> usize {
15        self.data.len() - 1
16    }
17}
18
19impl<T: FenwickTreeValue> std::ops::Index<TreeIndex> for FixedSizeFenwickTree<T> {
20    type Output = T;
21
22    fn index(&self, index: TreeIndex) -> &Self::Output {
23        &self.data[*index.to_internal()]
24    }
25}
26
27impl<T: FenwickTreeValue> std::ops::IndexMut<TreeIndex> for FixedSizeFenwickTree<T> {
28    fn index_mut(&mut self, index: TreeIndex) -> &mut Self::Output {
29        &mut self.data[*index.to_internal()]
30    }
31}
32
33impl<T: FenwickTreeValue> FenwickTree for FixedSizeFenwickTree<T> {
34    type Value = T;
35
36    fn query(&self, idx: usize) -> Result<T, TreeError> {
37        let idx: TreeIndex = idx.into();
38
39        if *idx >= self.size() {
40            return Err(TreeError::IndexOutOfBounds(*idx));
41        }
42
43        let mut res = T::default();
44        for data_position in idx.lsb_descending() {
45            let data_position = data_position.to_internal();
46            res.store_value(&self[data_position]);
47        }
48
49        Ok(res)
50    }
51
52    fn update(&mut self, idx: usize, value: Self::Value) -> Result<(), TreeError> {
53        let idx: TreeIndex = idx.into();
54
55        if *idx > self.data.len() {
56            return Err(TreeError::IndexOutOfBounds(*idx));
57        }
58
59        for data_position in idx.lsb_ascending(self.size()) {
60            let data_position = data_position.to_internal();
61            self[data_position].store_value(&value);
62        }
63
64        Ok(())
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use crate::fixed_size_tree::FixedSizeFenwickTree;
71    use crate::{FenwickTree, TreeError};
72    use rand::seq::SliceRandom;
73    use rand::Rng;
74
75    #[test]
76    fn edge_case() {
77        let mut tree = FixedSizeFenwickTree::<i32>::new(4);
78        tree.update(3, 1).unwrap();
79        assert_eq!(tree.query(3).unwrap(), 1);
80    }
81
82    #[test]
83    fn empty_tree_query() {
84        let tree = FixedSizeFenwickTree::<i32>::new(0);
85        assert!(tree.query(0).is_err());
86        assert!(tree.query(1).is_err());
87    }
88
89    #[test]
90    fn one_element_tree_query() {
91        let tree = FixedSizeFenwickTree::<i32>::new(1);
92        assert!(tree.query(0).is_ok());
93        assert!(tree.query(1).is_err());
94    }
95
96    #[test]
97    fn simple_tree_generation_with_queries() {
98        let mut tree = FixedSizeFenwickTree::<i32>::new(32);
99        for i in 0..32 {
100            if let Err(_) = tree.update(i, 1) {
101                assert!(false)
102            }
103        }
104        assert_eq!(tree.query(4).unwrap(), 5); // points at [0, 1, 2, 3, 4]
105        assert_eq!(tree.query(0).unwrap(), 1);
106        assert_eq!(tree.query(31).unwrap(), 32);
107    }
108
109    // TODO: #[should_panic]?
110    #[test]
111    fn tree_indexing_overflow() {
112        let tree = FixedSizeFenwickTree::<i32>::new(0);
113
114        match tree.query(1) {
115            Ok(_) => assert!(false),
116            Err(message) => assert_eq!(message, TreeError::IndexOutOfBounds(1)),
117        }
118    }
119
120    #[test]
121    fn update_existent_value() {
122        let mut tree = FixedSizeFenwickTree::<i32>::new(32);
123        for _i in 0..32 {
124            if let Err(_) = tree.update(0, 1) {
125                assert!(false)
126            }
127        }
128        let res = tree.query(1).unwrap();
129        assert_eq!(res, 32);
130    }
131
132    #[test]
133    fn random_100_point_data() {
134        let size = 100;
135        let mut input = vec![];
136        let mut rng = rand::thread_rng();
137
138        for _i in 0..size {
139            input.push((rng.gen::<f32>() * 100.0) as i32);
140        }
141
142        let mut tree = FixedSizeFenwickTree::<i32>::new(size);
143        for i in 0..size {
144            if let Err(_) = tree.update(i, *input.get(i).unwrap()) {
145                assert!(false)
146            }
147        }
148
149        let mut sum = 0;
150        for i in 0..size {
151            sum += *input.get(i).unwrap();
152
153            if let Ok(res) = tree.query(i) {
154                assert_eq!(res, sum);
155            } else {
156                assert!(false)
157            }
158        }
159    }
160
161    #[test]
162    fn random_100_point_data_with_random_update_order() {
163        let size = 100;
164        let mut input = vec![];
165        let mut rng = rand::thread_rng();
166
167        for _i in 0..size {
168            input.push((rng.gen::<f32>() * 100.0) as i32);
169        }
170
171        let mut tree = FixedSizeFenwickTree::<i32>::new(size);
172
173        let mut random_indexes: Vec<usize> = (0..size).collect();
174        random_indexes.shuffle(&mut rng);
175        for i in random_indexes {
176            if let Err(_) = tree.update(i, *input.get(i).unwrap()) {
177                assert!(false)
178            }
179        }
180
181        let mut sum = 0;
182        for i in 0..size {
183            sum += *input.get(i).unwrap();
184            if let Ok(res) = tree.query(i) {
185                assert_eq!(res, sum);
186            } else {
187                assert!(false);
188            }
189        }
190    }
191
192    #[test]
193    fn random_100_point_data_with_random_update_order_with_intermediate_asserts() {
194        let size = 100;
195        let mut input = vec![];
196        let mut rng = rand::thread_rng();
197
198        for _i in 0..size {
199            input.push((rng.gen::<f32>() * 100.0) as i32);
200        }
201
202        let mut tree = FixedSizeFenwickTree::<i32>::new(size);
203
204        let mut random_indexes: Vec<usize> = (0..size).collect();
205        random_indexes.shuffle(&mut rng);
206        for i in random_indexes {
207            let sum_before_update = tree.query(i).unwrap();
208            let value_to_update = *input.get(i).unwrap();
209            if let Err(_) = tree.update(i, value_to_update) {
210                assert!(false)
211            }
212            let sum_after_update = tree.query(i).unwrap();
213            assert_eq!(sum_after_update - sum_before_update, value_to_update)
214        }
215
216        let mut sum = 0;
217        for i in 0..size {
218            sum += *input.get(i).unwrap();
219
220            if let Ok(res) = tree.query(i) {
221                assert_eq!(res, sum);
222            } else {
223                assert!(false)
224            }
225        }
226    }
227}
228
229#[cfg(all(feature = "benchmarks", test))]
230mod benchmarks {
231    extern crate test;
232    use rand::seq::SliceRandom;
233    use rand::Rng;
234    use test::Bencher;
235
236    use crate::prelude::*;
237
238    fn bench_update(b: &mut Bencher, size: usize) {
239        let mut input = vec![];
240        let mut rng = rand::thread_rng();
241
242        for _i in 0..size {
243            input.push((rng.gen::<f32>() * 100.0) as i32);
244        }
245
246        let mut tree = FixedSizeFenwickTree::<i32>::new(size);
247
248        let random_indexes: Vec<usize> = (0..size).collect();
249
250        b.iter(|| {
251            let i = *random_indexes.choose(&mut rng).unwrap();
252            let value_to_update = *input.get(i).unwrap();
253            tree.update(i, value_to_update).unwrap()
254        });
255    }
256
257    fn bench_reads(b: &mut Bencher, size: usize) {
258        let mut input = vec![];
259        let mut rng = rand::thread_rng();
260
261        for _i in 0..size {
262            input.push((rng.gen::<f32>() * 100.0) as i32);
263        }
264
265        let mut tree = FixedSizeFenwickTree::<i32>::new(size);
266        let random_indexes: Vec<usize> = (0..size).collect();
267
268        for _i in 0..size {
269            let i = *random_indexes.choose(&mut rng).unwrap();
270            let value_to_update = *input.get(i).unwrap();
271            tree.update(i, value_to_update).unwrap()
272        }
273
274        b.iter(|| {
275            let i = *random_indexes.choose(&mut rng).unwrap();
276            tree.query(i).unwrap();
277        });
278    }
279
280    #[bench]
281    fn bench_1000_writes(b: &mut Bencher) {
282        bench_update(b, 1000);
283    }
284
285    #[bench]
286    fn bench_10000_writes(b: &mut Bencher) {
287        bench_update(b, 10000);
288    }
289
290    #[bench]
291    fn bench_100000_writes(b: &mut Bencher) {
292        bench_update(b, 100000);
293    }
294
295    #[bench]
296    fn bench_10000000_writes(b: &mut Bencher) {
297        bench_update(b, 10000000);
298    }
299
300    #[bench]
301    fn bench_1000_reads(b: &mut Bencher) {
302        bench_reads(b, 1000);
303    }
304
305    #[bench]
306    fn bench_10000_reads(b: &mut Bencher) {
307        bench_reads(b, 10000);
308    }
309
310    #[bench]
311    fn bench_100000_reads(b: &mut Bencher) {
312        bench_reads(b, 100000);
313    }
314
315    #[bench]
316    fn bench_10000000_reads(b: &mut Bencher) {
317        bench_reads(b, 10000000);
318    }
319}