1#![doc = include_str!("../README.mkd")]
2
3#[derive(Debug)]
27pub struct PrefixSumVec<T, Idx = usize> {
28    indices: Vec<Idx>,
30    values: Vec<T>,
31}
32
33impl<T, Idx> PrefixSumVec<T, Idx> {
34    pub fn new() -> Self {
38        Self {
39            indices: vec![],
40            values: vec![],
41        }
42    }
43
44    pub fn clear(&mut self) {
49        self.indices.clear();
51        self.values.clear();
52    }
53
54    pub fn max_index(&self) -> Option<&Idx> {
61        self.indices.last()
62    }
63
64    fn grow_if_necessary(&mut self) -> Result<(), std::collections::TryReserveError> {
65        if self.values.len() == self.values.capacity() {
66            self.values.try_reserve(1)?;
67        }
68        if self.indices.len() == self.indices.capacity() {
69            self.values.try_reserve(1)?;
70        }
71        Ok(())
72    }
73}
74
75impl<T, Idx: Ord> PrefixSumVec<T, Idx> {
76    pub fn get(&self, index: &Idx) -> Option<&T> {
82        match self.indices.binary_search(index) {
83            Ok(i) | Err(i) => self.values.get(i),
92        }
93    }
94}
95
96impl<T, Idx: Index> PrefixSumVec<T, Idx> {
97
98    fn new_index(&self, additional_count: Idx) -> Result<Idx, TryPushError> {
99        match self.max_index() {
100            Some(current_max) => additional_count
101                .checked_add(current_max)
102                .ok_or(TryPushError::Overflow),
103            None => Ok(additional_count.decrement()),
104        }
105    }
106
107    pub fn try_push_many(&mut self, count: Idx, value: T) -> Result<(), TryPushError> {
115        if count.is_zero() {
116            return Ok(());
117        }
118        let new_index = self.new_index(count)?;
119        self.grow_if_necessary().map_err(TryPushError::Reserve)?;
120        self.indices.push(new_index);
121        self.values.push(value);
122        Ok(())
123    }
124}
125
126impl<T: PartialEq, Idx: Index> PrefixSumVec<T, Idx> {
127    pub fn try_push_more(&mut self, count: Idx, value: T) -> Result<(), TryPushError> {
135        if count.is_zero() {
136            return Ok(());
137        }
138        if let Some(lastval) = self.values.last_mut() {
139            if PartialEq::eq(&*lastval, &value) {
140                let new_index = self.new_index(count)?;
142                let old_index = self.indices.pop();
143                self.indices.push(new_index);
144                drop(old_index);
147                return Ok(());
148            }
149        }
150        self.try_push_many(count, value)
151    }
152}
153
154pub trait Index: Sized {
156    fn is_zero(&self) -> bool;
158    fn decrement(self) -> Self;
162    fn checked_add(self, other: &Self) -> Option<Self>;
166}
167
168macro_rules! impl_primitive_index {
169    ($($ty: ty),*) => {
170        $(impl Index for $ty {
171            fn is_zero(&self) -> bool { *self == 0 }
172            fn decrement(self) -> Self { self - 1 }
173            fn checked_add(self, other: &Self) -> Option<Self> { self.checked_add(*other) }
174        })*
175    }
176}
177
178impl_primitive_index!(u8, u16, u32, u64, u128, usize);
179impl_primitive_index!(i8, i16, i32, i64, i128, isize);
180
181impl<K, Idx: Ord> std::ops::Index<Idx> for PrefixSumVec<K, Idx> {
182    type Output = K;
183
184    fn index(&self, index: Idx) -> &Self::Output {
185        self.get(&index).expect("index out of range")
186    }
187}
188
189impl<K, Idx: Ord> std::ops::Index<&Idx> for PrefixSumVec<K, Idx> {
190    type Output = K;
191
192    fn index(&self, index: &Idx) -> &Self::Output {
193        self.get(index).expect("index out of range")
194    }
195}
196
197#[non_exhaustive]
198#[derive(Debug, PartialEq, Eq, Clone)]
199pub enum TryPushError {
200    Reserve(std::collections::TryReserveError),
202    Overflow,
204}
205
206impl std::error::Error for TryPushError {}
207impl std::fmt::Display for TryPushError {
208    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
209        f.write_str(match self {
210            TryPushError::Reserve(_) => "could not reserve additional capacity",
211            TryPushError::Overflow => "the index type overflowed",
212        })
213    }
214}
215
216pub struct CompressedIter<'a, T, Idx> {
219    inner: std::iter::Zip<std::slice::Iter<'a, Idx>, std::slice::Iter<'a, T>>,
220}
221
222impl<'a, T, Idx> Iterator for CompressedIter<'a, T, Idx> {
223    type Item = (&'a Idx, &'a T);
224
225    fn next(&mut self) -> Option<Self::Item> {
226        self.inner.next()
227    }
228
229    fn size_hint(&self) -> (usize, Option<usize>) {
230        self.inner.size_hint()
231    }
232
233    fn count(self) -> usize {
234        self.inner.count()
235    }
236
237    fn last(self) -> Option<Self::Item> {
238        self.inner.last()
239    }
240
241    fn nth(&mut self, n: usize) -> Option<Self::Item> {
242        self.inner.nth(n)
243    }
244
245    fn for_each<F: FnMut(Self::Item)>(self, f: F) {
246        self.inner.for_each(f)
247    }
248
249    fn collect<B: std::iter::FromIterator<Self::Item>>(self) -> B {
250        self.inner.collect()
251    }
252
253    fn partition<B, F>(self, f: F) -> (B, B)
254    where
255        B: Default + Extend<Self::Item>,
256        F: FnMut(&Self::Item) -> bool,
257    {
258        self.inner.partition(f)
259    }
260
261    fn fold<B, F>(self, init: B, f: F) -> B
262    where
263        F: FnMut(B, Self::Item) -> B,
264    {
265        self.inner.fold(init, f)
266    }
267
268    fn reduce<F>(self, f: F) -> Option<Self::Item>
269    where
270        F: FnMut(Self::Item, Self::Item) -> Self::Item,
271    {
272        self.inner.reduce(f)
273    }
274
275    fn all<F>(&mut self, f: F) -> bool
276    where
277        F: FnMut(Self::Item) -> bool,
278    {
279        self.inner.all(f)
280    }
281
282    fn any<F: FnMut(Self::Item) -> bool>(&mut self, f: F) -> bool {
283        self.inner.any(f)
284    }
285
286    fn find<P: FnMut(&Self::Item) -> bool>(&mut self, predicate: P) -> Option<Self::Item> {
287        self.inner.find(predicate)
288    }
289
290    fn find_map<B, F: FnMut(Self::Item) -> Option<B>>(&mut self, f: F) -> Option<B> {
291        self.inner.find_map(f)
292    }
293
294    fn position<P: FnMut(Self::Item) -> bool>(&mut self, predicate: P) -> Option<usize> {
295        self.inner.position(predicate)
296    }
297
298    fn rposition<P: FnMut(Self::Item) -> bool>(&mut self, predicate: P) -> Option<usize> {
299        self.inner.rposition(predicate)
300    }
301
302    fn max(self) -> Option<Self::Item>
303    where
304        Self::Item: Ord,
305    {
306        self.inner.max()
307    }
308
309    fn min(self) -> Option<Self::Item>
310    where
311        Self::Item: Ord,
312    {
313        self.inner.min()
314    }
315
316    fn max_by_key<B: Ord, F: FnMut(&Self::Item) -> B>(self, f: F) -> Option<Self::Item> {
317        self.inner.max_by_key(f)
318    }
319
320    fn max_by<F>(self, compare: F) -> Option<Self::Item>
321    where
322        F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,
323    {
324        self.inner.max_by(compare)
325    }
326
327    fn min_by_key<B: Ord, F: FnMut(&Self::Item) -> B>(self, f: F) -> Option<Self::Item> {
328        self.inner.min_by_key(f)
329    }
330
331    fn min_by<F>(self, compare: F) -> Option<Self::Item>
332    where
333        F: FnMut(&Self::Item, &Self::Item) -> std::cmp::Ordering,
334    {
335        self.inner.min_by(compare)
336    }
337
338    fn sum<S: std::iter::Sum<Self::Item>>(self) -> S {
339        self.inner.sum()
340    }
341
342    fn product<P: std::iter::Product<Self::Item>>(self) -> P {
343        self.inner.product()
344    }
345
346    fn cmp<I>(self, other: I) -> std::cmp::Ordering
347    where
348        I: IntoIterator<Item = Self::Item>,
349        Self::Item: Ord,
350    {
351        self.inner.cmp(other)
352    }
353
354    fn partial_cmp<I>(self, other: I) -> Option<std::cmp::Ordering>
355    where
356        I: IntoIterator,
357        Self::Item: PartialOrd<I::Item>,
358    {
359        self.inner.partial_cmp(other)
360    }
361
362    fn eq<I>(self, other: I) -> bool
363    where
364        I: IntoIterator,
365        Self::Item: PartialEq<I::Item>,
366    {
367        self.inner.eq(other)
368    }
369
370    fn ne<I>(self, other: I) -> bool
371    where
372        I: IntoIterator,
373        Self::Item: PartialEq<I::Item>,
374    {
375        self.inner.ne(other)
376    }
377
378    fn lt<I>(self, other: I) -> bool
379    where
380        I: IntoIterator,
381        Self::Item: PartialOrd<I::Item>,
382    {
383        self.inner.lt(other)
384    }
385
386    fn le<I>(self, other: I) -> bool
387    where
388        I: IntoIterator,
389        Self::Item: PartialOrd<I::Item>,
390        Self: Sized,
391    {
392        self.inner.le(other)
393    }
394
395    fn gt<I>(self, other: I) -> bool
396    where
397        I: IntoIterator,
398        Self::Item: PartialOrd<I::Item>,
399    {
400        self.inner.gt(other)
401    }
402
403    fn ge<I>(self, other: I) -> bool
404    where
405        I: IntoIterator,
406        Self::Item: PartialOrd<I::Item>,
407    {
408        self.inner.ge(other)
409    }
410}
411
412impl<'a, T, Idx> DoubleEndedIterator for CompressedIter<'a, T, Idx> {
413    fn next_back(&mut self) -> Option<Self::Item> {
414        self.inner.next_back()
415    }
416}
417
418impl<'a, T, Idx> ExactSizeIterator for CompressedIter<'a, T, Idx> {
419    fn len(&self) -> usize {
420        self.inner.len()
421    }
422}
423
424impl<'a, T, Idx> std::iter::FusedIterator for CompressedIter<'a, T, Idx> {}
425impl<'a, T, Idx> CompressedIter<'a, T, Idx> {
426    #[allow(dead_code)]
427    fn _assert_fused_iterator(mut self) {
428        fn is_fused<T: std::iter::FusedIterator>(_: T) {}
429        is_fused(&mut self.inner);
430    }
431}
432
433impl<'a, T, Idx> IntoIterator for &'a PrefixSumVec<T, Idx> {
434    type Item = (&'a Idx, &'a T);
435    type IntoIter = CompressedIter<'a, T, Idx>;
436    fn into_iter(self) -> Self::IntoIter {
437        CompressedIter {
438            inner: self.indices.iter().zip(self.values.iter()),
439        }
440    }
441}
442
443#[cfg(test)]
456mod tests {
457    use super::{PrefixSumVec, TryPushError};
458
459    #[test]
460    fn empty_partial_map() {
461        let map = PrefixSumVec::<u32, u32>::new();
462        assert_eq!(None, map.get(&0));
463        assert_eq!(None, map.max_index());
464    }
465
466    #[test]
467    fn basic_function() {
468        let mut map = PrefixSumVec::<u32, u32>::new();
469        assert_eq!(None, map.max_index());
470        for i in 0..10 {
471            map.try_push_many(1, i).unwrap();
472            assert_eq!(Some(&i), map.max_index());
473        }
474        for i in 0..10 {
475            assert_eq!(Some(&i), map.get(&i));
476        }
477        assert_eq!(None, map.get(&10));
478        assert_eq!(None, map.get(&0xFFFF_FFFF));
479    }
480
481    #[test]
482    fn zero_count() {
483        let mut map = PrefixSumVec::<u32, u32>::new();
484        assert_eq!(Ok(()), map.try_push_many(0, 0));
485        assert_eq!(None, map.max_index());
486        assert_eq!(Ok(()), map.try_push_many(10, 42));
487        assert_eq!(Some(&9), map.max_index());
488        assert_eq!(Ok(()), map.try_push_many(0, 43));
489        assert_eq!(Some(&9), map.max_index());
490    }
491
492    #[test]
493    fn close_to_limit() {
494        let mut map = PrefixSumVec::<u32, u32>::new();
495        assert_eq!(Ok(()), map.try_push_many(0xFFFF_FFFE, 42));
496        assert_eq!(Some(&42), map.get(&0xFFFF_FFFD));
498        assert_eq!(None, map.get(&0xFFFF_FFFE));
499
500        assert_eq!(Err(TryPushError::Overflow), map.try_push_many(100, 93));
501        assert_eq!(Some(&42), map.get(&0xFFFF_FFFD));
503        assert_eq!(None, map.get(&0xFFFF_FFFE));
504
505        assert_eq!(Ok(()), map.try_push_many(1, 322));
506        assert_eq!(Some(&42), map.get(&0xFFFF_FFFD));
508        assert_eq!(Some(&322), map.get(&0xFFFF_FFFE));
509        assert_eq!(None, map.get(&0xFFFF_FFFF));
510
511        assert_eq!(Err(TryPushError::Overflow), map.try_push_many(2, 1234));
512        assert_eq!(Some(&42), map.get(&0xFFFF_FFFD));
514        assert_eq!(Some(&322), map.get(&0xFFFF_FFFE));
515        assert_eq!(Some(&0xFFFF_FFFE), map.max_index());
516        assert_eq!(None, map.get(&0xFFFF_FFFF));
517
518        assert_eq!(Ok(()), map.try_push_many(1, 1234));
519        assert_eq!(Some(&42), map.get(&0xFFFF_FFFD));
521        assert_eq!(Some(&322), map.get(&0xFFFF_FFFE));
522        assert_eq!(Some(&0xFFFF_FFFF), map.max_index());
523        assert_eq!(Some(&1234), map.get(&0xFFFF_FFFF));
524
525        assert_eq!(Ok(()), map.try_push_many(0, 12345));
526        assert_eq!(Err(TryPushError::Overflow), map.try_push_many(1, 12345));
528    }
529
530    #[test]
531    fn try_push_more() {
532        let mut map = PrefixSumVec::<u32, u32>::new();
533        assert_eq!(Ok(()), map.try_push_more(0, 0));
534        assert_eq!(None, map.max_index());
535        assert_eq!(Ok(()), map.try_push_more(10, 42));
536        assert_eq!(Some(&9), map.max_index());
537        assert_eq!(Ok(()), map.try_push_more(0, 43));
538        assert_eq!(Some(&9), map.max_index());
539        assert_eq!(Ok(()), map.try_push_more(10, 42));
540        assert_eq!(Some(&19), map.max_index());
541        assert_eq!(Ok(()), map.try_push_more(10, 44));
542        assert_eq!(Some(&29), map.max_index());
543        let representation = map.into_iter().map(|(&a, &b)| (a, b)).collect::<Vec<_>>();
544        assert_eq!(vec![(19, 42), (29, 44)], representation);
545    }
546}