threshold/set/
above_range.rs

1//! This module contains an implementation of an above-extra-range set.
2//!
3//! # Examples
4//! ```
5//! use threshold::*;
6//!
7//! let mut above_range_set = AboveRangeSet::new();
8//! assert_eq!(above_range_set.next_event(), 1);
9//! assert!(above_range_set.is_event(1));
10//! assert!(!above_range_set.is_event(2));
11//!
12//! let other = AboveRangeSet::from_event(3);
13//! assert!(!other.is_event(1));
14//! assert!(!other.is_event(2));
15//! assert!(other.is_event(3));
16//!
17//! above_range_set.join(&other);
18//! assert!(above_range_set.is_event(1));
19//! assert!(!above_range_set.is_event(2));
20//! assert!(above_range_set.is_event(3));
21//! ```
22
23use crate::EventSet;
24use serde::{Deserialize, Serialize};
25use std::cmp;
26use std::cmp::Ordering;
27use std::collections::btree_map::{self, BTreeMap};
28use std::collections::HashMap;
29use std::fmt;
30use std::iter::FromIterator;
31
32#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
33pub struct AboveRangeSet {
34    // Highest contiguous event seen
35    max: u64,
36    // Set of extra events encoded as ranges
37    ranges: Ranges,
38}
39
40#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
41pub struct Ranges {
42    // Mapping from start of the range to its end (sorted ASC)
43    ranges: HashMap<u64, u64>,
44}
45
46impl EventSet for AboveRangeSet {
47    type EventIter = EventIter;
48
49    /// Returns a new `AboveRangeSet` instance.
50    fn new() -> Self {
51        AboveRangeSet {
52            max: 0,
53            ranges: Ranges::new(),
54        }
55    }
56
57    /// Generates the next event.
58    /// There should be no extra ranges when calling this.
59    ///
60    /// # Examples
61    /// ```
62    /// use threshold::*;
63    ///
64    /// let mut above_range_set = AboveRangeSet::new();
65    /// assert_eq!(above_range_set.next_event(), 1);
66    /// assert_eq!(above_range_set.next_event(), 2);
67    /// ```
68    fn next_event(&mut self) -> u64 {
69        debug_assert!(self.ranges.is_empty());
70        self.max += 1;
71        self.max
72    }
73
74    /// Adds an event to the set.
75    /// Returns `true` if it's a new event.
76    ///
77    /// # Examples
78    /// ```
79    /// use threshold::*;
80    ///
81    /// let mut above_range_set = AboveRangeSet::new();
82    ///
83    /// above_range_set.add_event(1);
84    /// assert!(above_range_set.is_event(1));
85    /// assert!(!above_range_set.is_event(2));
86    ///
87    /// above_range_set.add_event(3);
88    /// assert!(above_range_set.is_event(1));
89    /// assert!(!above_range_set.is_event(2));
90    /// assert!(above_range_set.is_event(3));
91    ///
92    /// above_range_set.add_event(2);
93    /// assert!(above_range_set.is_event(1));
94    /// assert!(above_range_set.is_event(2));
95    /// assert!(above_range_set.is_event(3));
96    /// ```
97    fn add_event(&mut self, event: u64) -> bool {
98        let next_max = self.max + 1;
99        match event.cmp(&next_max) {
100            Ordering::Equal => {
101                // this event is now the new max
102                self.max = event;
103
104                // maybe compress
105                self.try_compress();
106
107                // new event, so `true`
108                true
109            }
110            Ordering::Greater => {
111                // add as a range: assumes it's a new range
112                self.ranges.add(event, event);
113                true
114            }
115            Ordering::Less => {
116                // else it's already an event
117                false
118            }
119        }
120    }
121
122    /// Adds a range of events to the set.
123    fn add_event_range(&mut self, start: u64, end: u64) -> bool {
124        if start <= self.max + 1 && end > self.max {
125            // the end of the range is now the new max
126            self.max = end;
127
128            // maybe compress
129            self.try_compress();
130
131            // new event, so `true`
132            true
133        } else if start > self.max + 1 {
134            // add as a range: assumes it's a new range
135            self.ranges.add(start, end);
136            true
137        } else {
138            // else all events are already an event
139            false
140        }
141    }
142
143    /// Checks if an event is part of the set.
144    ///
145    /// # Examples
146    /// ```
147    /// use threshold::*;
148    ///
149    /// let mut above_range_set = AboveRangeSet::new();
150    /// let event = above_range_set.next_event();
151    /// assert!(above_range_set.is_event(event));
152    ///
153    /// above_range_set.add_event(3);
154    /// assert!(!above_range_set.is_event(2));
155    /// assert!(above_range_set.is_event(3));
156    /// ```
157    fn is_event(&self, event: u64) -> bool {
158        event <= self.max || self.ranges.contains(&event)
159    }
160
161    /// Returns all events seen as a tuple.
162    /// The first component is the highest event seen, while the second is a
163    /// vector with the exceptions (in no specific order).
164    ///
165    /// # Examples
166    /// ```
167    /// use threshold::*;
168    ///
169    /// let mut above_range_set = AboveRangeSet::new();
170    ///
171    /// above_range_set.add_event(1);
172    /// assert_eq!(above_range_set.events(), (1, vec![]));
173    ///
174    /// above_range_set.add_event(3);
175    /// assert_eq!(above_range_set.events(), (1, vec![3]));
176    ///
177    /// above_range_set.add_event(2);
178    /// assert_eq!(above_range_set.events(), (3, vec![]));
179    ///
180    /// above_range_set.add_event(4);
181    /// assert_eq!(above_range_set.events(), (4, vec![]));
182    ///
183    /// above_range_set.add_event(6);
184    /// assert_eq!(above_range_set.events(), (4, vec![6]));
185    /// ```
186    fn events(&self) -> (u64, Vec<u64>) {
187        (self.max, self.ranges.clone().event_iter().collect())
188    }
189
190    /// Returns the frontier (the highest contiguous event seen).
191    ///
192    /// # Examples
193    /// ```
194    /// use threshold::*;
195    ///
196    /// let mut above_range_set = AboveRangeSet::new();
197    /// assert_eq!(above_range_set.frontier(), 0);
198    ///
199    /// above_range_set.add_event(1);
200    /// assert_eq!(above_range_set.frontier(), 1);
201    ///
202    /// above_range_set.add_event(3);
203    /// assert_eq!(above_range_set.frontier(), 1);
204    ///
205    /// above_range_set.add_event(2);
206    /// assert_eq!(above_range_set.frontier(), 3);
207    ///
208    /// above_range_set.add_event(4);
209    /// assert_eq!(above_range_set.frontier(), 4);
210    ///
211    /// above_range_set.add_event(6);
212    /// assert_eq!(above_range_set.frontier(), 4);
213    /// ```
214    fn frontier(&self) -> u64 {
215        self.max
216    }
217
218    /// Merges `other` `AboveRangeSet` into `self`.
219    ///
220    /// # Examples
221    /// ```
222    /// use threshold::*;
223    ///
224    /// let mut above_range_set = AboveRangeSet::new();
225    /// above_range_set.add_event(1);
226    /// above_range_set.add_event(3);
227    /// above_range_set.add_event(4);
228    /// assert_eq!(above_range_set.events(), (1, vec![3, 4]));
229    ///
230    /// above_range_set.join(&AboveRangeSet::from_event(3));
231    /// assert_eq!(above_range_set.events(), (1, vec![3, 4]));
232    ///
233    /// above_range_set.join(&AboveRangeSet::from_event(5));
234    /// assert_eq!(above_range_set.events(), (1, vec![3, 4, 5]));
235    ///
236    /// let mut other = AboveRangeSet::new();
237    /// other.add_event(2);
238    /// other.add_event(7);
239    /// above_range_set.join(&other);
240    /// assert_eq!(above_range_set.events(), (5, vec![7]));
241    /// ```
242    fn join(&mut self, other: &Self) {
243        // the new max value is the max of both max values
244        self.max = cmp::max(self.max, other.max);
245
246        // join ranges
247        self.ranges.join(&other.ranges, self.max);
248
249        // maybe compress
250        self.try_compress();
251    }
252
253    fn meet(&mut self, _other: &Self) {
254        todo!("AboveRangeSet::meet not yet implemented")
255    }
256
257    fn subtracted(&self, _other: &Self) -> Vec<u64> {
258        todo!("AboveRangeSet::subtracted not yet implemented")
259    }
260
261    /// Returns a `AboveRangeSet` event iterator with all events from lowest to
262    /// highest.
263    ///
264    /// # Examples
265    /// ```
266    /// use threshold::*;
267    ///
268    /// let mut above_range_set = AboveRangeSet::new();
269    /// above_range_set.add_event(3);
270    /// above_range_set.add_event(5);
271    ///
272    /// let mut iter = above_range_set.event_iter();
273    /// assert_eq!(iter.next(), Some(3));
274    /// assert_eq!(iter.next(), Some(5));
275    /// assert_eq!(iter.next(), None);
276    /// ```
277    fn event_iter(self) -> Self::EventIter {
278        EventIter {
279            current: 0,
280            max: self.max,
281            ranges: self.ranges.event_iter(),
282        }
283    }
284}
285
286impl AboveRangeSet {
287    /// Tries to set a new max contiguous event.
288    fn try_compress(&mut self) {
289        // drop the first range while its start is right after the max
290        while let Some(new_max) = self.ranges.try_drop(self.max + 1) {
291            self.max = new_max;
292        }
293    }
294
295    /// Creates a new instance from the highest contiguous event, and a sequence
296    /// of extra events.
297    ///
298    /// # Examples
299    /// ```
300    /// use threshold::*;
301    ///
302    /// let above_range_set = AboveRangeSet::from(0, vec![2, 4, 5]);
303    /// assert!(!above_range_set.is_event(1));
304    /// assert!(above_range_set.is_event(2));
305    /// assert!(!above_range_set.is_event(3));
306    /// assert!(above_range_set.is_event(4));
307    /// assert!(above_range_set.is_event(5));
308    /// assert!(!above_range_set.is_event(6));
309    /// ```
310    pub fn from<I: IntoIterator<Item = u64>>(max: u64, iter: I) -> Self {
311        let ranges = Ranges::from::<I>(iter);
312        AboveRangeSet { max, ranges }
313    }
314}
315
316pub struct EventIter {
317    // Last contiguous value returned by the iterator
318    current: u64,
319    // Last contiguous value that should be returned by the iterator
320    max: u64,
321    // Iterator of extra ranges
322    ranges: RangesIter,
323}
324
325impl Iterator for EventIter {
326    type Item = u64;
327
328    fn next(&mut self) -> Option<Self::Item> {
329        if self.current == self.max {
330            // we've reached the last contiguous, just call next on the extra
331            // ranges iterator
332            self.ranges.next()
333        } else {
334            // compute next value
335            self.current += 1;
336            Some(self.current)
337        }
338    }
339}
340
341impl fmt::Debug for AboveRangeSet {
342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343        if self.ranges.is_empty() {
344            write!(f, "{}", self.max)
345        } else {
346            write!(f, "({} + {:?})", self.max, self.ranges)
347        }
348    }
349}
350
351impl Ranges {
352    /// Creates a new `Ranges` instance.
353    fn new() -> Self {
354        Ranges {
355            ranges: HashMap::new(),
356        }
357    }
358
359    /// Checks if there are no ranges.
360    fn is_empty(&self) -> bool {
361        self.ranges.is_empty()
362    }
363
364    /// Adds a new range, assuming it is new, i.e.:
365    /// - none of the events within the range have already been added.
366    fn add(&mut self, start: u64, end: u64) {
367        self.ranges.insert(start, end);
368    }
369
370    /// Adds a new range, assuming it is new, i.e.:
371    /// - none of the events within the range have already been added.
372    /// TODO it didn't look worth compressing so we moved from BTreeMap to
373    /// HashMap
374    // fn add_and_compress(&mut self, start: u64, mut end: u64) {
375    //     // split map where the new range should be inserted
376    //     let mut after_new_range = self.ranges.split_off(&start);
377
378    //     let mut inserted = false;
379
380    //     // check if the previous range can be extended with the new range
381    //     if let Some(mut before) = self.ranges.last_entry() {
382    //         let before_end = before.get_mut();
383    //         if *before_end + 1 == start {
384    //             // extend the previous range
385    //             *before_end = end;
386
387    //             // check if we can also extend this range with the first
388    // range             // in the splitted off ranges
389    //             if let Some(after) = after_new_range.first_entry() {
390    //                 if *before_end + 1 == *after.key() {
391    //                     // remove entry and extend range again
392    //                     *before_end = after.remove();
393    //                 }
394    //             }
395    //             // we're done, we only need to merge the splitted off ranges
396    //             inserted = true;
397    //         }
398    //     }
399
400    //     // if here haven't extended the previous range, then we need to
401    // create a     // new one
402    //     if !inserted {
403    //         // check if we should create a new one with the provided `end`,
404    // or         // with the end of the next range (in case they can be
405    // merged)         if let Some(after) = after_new_range.first_entry() {
406    //             if end + 1 == *after.key() {
407    //                 // remove entry and extend new range to be added
408    //                 end = after.remove();
409    //             }
410    //         }
411
412    //         // insert new range
413    //         self.ranges.insert(start, end);
414    //     }
415
416    //     // extend map with the ranges that have been splitted off
417    //     self.ranges.append(&mut after_new_range);
418    // }
419
420    /// Checks if the event is part of any of the ranges. This implementation
421    /// makes no effort in being efficient.
422    fn contains(&self, event: &u64) -> bool {
423        self.ranges
424            .iter()
425            .any(|(start, end)| start <= event && event <= end)
426    }
427
428    /// Joins two ranges. This implementation makes no effort in being
429    /// efficient.
430    fn join(&mut self, other: &Self, max: u64) {
431        let mut result = Ranges::new();
432
433        // add all events from self that are higher than the new max
434        for event in self.clone().event_iter() {
435            if event > max {
436                result.add(event, event);
437            }
438        }
439
440        // add all events from `other` that are higher than the new max
441        // AND haven't been added yet
442        for event in other.clone().event_iter() {
443            if event > max && !result.contains(&event) {
444                result.add(event, event);
445            }
446        }
447
448        self.ranges = result.ranges;
449    }
450
451    /// Creates a iterator for all events represented by the ranges. This
452    /// implementation makes no effort in being efficient.
453    fn event_iter(self) -> RangesIter {
454        RangesIter {
455            current: None,
456            ranges: BTreeMap::from_iter(self.ranges).into_iter(),
457        }
458    }
459
460    /// Creates a new `Ranges` from a set of events.
461    /// Assumes there are no repeated events.
462    fn from<I: IntoIterator<Item = u64>>(iter: I) -> Self {
463        let mut result = Ranges::new();
464        for event in iter {
465            result.add(event, event);
466        }
467        result
468    }
469
470    /// Try to drop the range. If it succeeds then it can be used to update the
471    /// maximum value.
472    fn try_drop(&mut self, next: u64) -> Option<u64> {
473        self.ranges.remove(&next)
474    }
475}
476
477pub struct RangesIter {
478    current: Option<(u64, u64)>,
479    ranges: btree_map::IntoIter<u64, u64>,
480}
481
482impl Iterator for RangesIter {
483    type Item = u64;
484
485    fn next(&mut self) -> Option<Self::Item> {
486        // if currently iterating a range, then keep going
487        if let Some((val, end)) = self.current {
488            if val <= end {
489                self.current = Some((val + 1, end));
490                return Some(val);
491            }
492        }
493
494        // if we haven't returned a new value from the current range, try again
495        // in the next range
496        self.current = self.ranges.next();
497        if self.current.is_none() {
498            // if there's no next range, we're done
499            None
500        } else {
501            self.next()
502        }
503    }
504}
505
506impl fmt::Debug for Ranges {
507    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
508        write!(f, "{:?}", self.ranges)
509    }
510}