threshold/set/
above_ex.rs

1//! This module contains an implementation of an above-extra set.
2//!
3//! # Examples
4//! ```
5//! use threshold::*;
6//!
7//! let mut above_exset = AboveExSet::new();
8//! assert_eq!(above_exset.next_event(), 1);
9//! assert!(above_exset.is_event(1));
10//! assert!(!above_exset.is_event(2));
11//!
12//! let other = AboveExSet::from_event(3);
13//! assert!(!other.is_event(1));
14//! assert!(!other.is_event(2));
15//! assert!(other.is_event(3));
16//!
17//! above_exset.join(&other);
18//! assert!(above_exset.is_event(1));
19//! assert!(!above_exset.is_event(2));
20//! assert!(above_exset.is_event(3));
21//! ```
22
23use crate::EventSet;
24use serde::{Deserialize, Serialize};
25use std::cmp::{self, Ordering};
26use std::collections::btree_set::{self, BTreeSet};
27use std::collections::HashSet;
28use std::fmt;
29use std::iter::FromIterator;
30
31#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
32pub struct AboveExSet {
33    // Highest contiguous event seen
34    max: u64,
35    // Set of extra events above the highest (sorted ASC)
36    exs: HashSet<u64>,
37}
38
39impl EventSet for AboveExSet {
40    type EventIter = EventIter;
41
42    /// Returns a new `AboveExSet` instance.
43    fn new() -> Self {
44        AboveExSet {
45            max: 0,
46            exs: HashSet::new(),
47        }
48    }
49
50    /// Generates the next event.
51    /// There should be no extras when calling this.
52    ///
53    /// # Examples
54    /// ```
55    /// use threshold::*;
56    ///
57    /// let mut above_exset = AboveExSet::new();
58    /// assert_eq!(above_exset.next_event(), 1);
59    /// assert_eq!(above_exset.next_event(), 2);
60    /// ```
61    fn next_event(&mut self) -> u64 {
62        debug_assert!(self.exs.is_empty());
63        self.max += 1;
64        self.max
65    }
66
67    /// Adds an event to the set.
68    /// Returns `true` if it's a new event.
69    ///
70    /// # Examples
71    /// ```
72    /// use threshold::*;
73    ///
74    /// let mut above_exset = AboveExSet::new();
75    ///
76    /// above_exset.add_event(1);
77    /// assert!(above_exset.is_event(1));
78    /// assert!(!above_exset.is_event(2));
79    ///
80    /// above_exset.add_event(3);
81    /// assert!(above_exset.is_event(1));
82    /// assert!(!above_exset.is_event(2));
83    /// assert!(above_exset.is_event(3));
84    ///
85    /// above_exset.add_event(2);
86    /// assert!(above_exset.is_event(1));
87    /// assert!(above_exset.is_event(2));
88    /// assert!(above_exset.is_event(3));
89    /// ```
90    fn add_event(&mut self, event: u64) -> bool {
91        let next_max = self.max + 1;
92        match event.cmp(&next_max) {
93            Ordering::Equal => {
94                // this event is now the new max
95                self.max = event;
96
97                // maybe compress
98                self.try_compress();
99
100                // new event, so `true`
101                true
102            }
103            Ordering::Greater => {
104                // add as an extra. the result is the same as the result of the
105                // insert in the extras:
106                // - if it's a new extra, then it's also a new event
107                self.exs.insert(event)
108            }
109            Ordering::Less => {
110                // else it's already an event
111                false
112            }
113        }
114    }
115
116    /// Adds a range of events to the set.
117    fn add_event_range(&mut self, start: u64, end: u64) -> bool {
118        if start <= self.max + 1 && end > self.max {
119            // the end of the range is now the new max
120            self.max = end;
121
122            // remove extras smaller than `self.max`
123            let max = self.max;
124            self.exs.retain(|ex| *ex > max);
125
126            // maybe compress
127            self.try_compress();
128
129            // new event, so `true`
130            true
131        } else if start > self.max + 1 {
132            // add all events as extra
133            self.exs.extend(start..=end);
134            true
135        } else {
136            // else all events are already an event
137            false
138        }
139    }
140
141    /// Checks if an event is part of the set.
142    ///
143    /// # Examples
144    /// ```
145    /// use threshold::*;
146    ///
147    /// let mut above_exset = AboveExSet::new();
148    /// let event = above_exset.next_event();
149    /// assert!(above_exset.is_event(event));
150    ///
151    /// above_exset.add_event(3);
152    /// assert!(!above_exset.is_event(2));
153    /// assert!(above_exset.is_event(3));
154    /// ```
155    fn is_event(&self, event: u64) -> bool {
156        event <= self.max || self.exs.contains(&event)
157    }
158
159    /// Returns all events seen as a tuple.
160    /// The first component is the highest event seen, while the second is a
161    /// vector with the exceptions (in no specific order).
162    ///
163    /// # Examples
164    /// ```
165    /// use threshold::*;
166    ///
167    /// let mut above_exset = AboveExSet::new();
168    ///
169    /// above_exset.add_event(1);
170    /// assert_eq!(above_exset.events(), (1, vec![]));
171    ///
172    /// above_exset.add_event(3);
173    /// assert_eq!(above_exset.events(), (1, vec![3]));
174    ///
175    /// above_exset.add_event(2);
176    /// assert_eq!(above_exset.events(), (3, vec![]));
177    ///
178    /// above_exset.add_event(4);
179    /// assert_eq!(above_exset.events(), (4, vec![]));
180    ///
181    /// above_exset.add_event(6);
182    /// assert_eq!(above_exset.events(), (4, vec![6]));
183    /// ```
184    fn events(&self) -> (u64, Vec<u64>) {
185        let mut exs: Vec<_> = self.exs.clone().into_iter().collect();
186        exs.sort_unstable();
187        (self.max, exs)
188    }
189
190    /// Returns the frontier (the highest contiguous event seen).
191    ///
192    /// # Examples
193    /// ```
194    /// use threshold::*;
195    ///
196    /// let mut above_exset = AboveExSet::new();
197    /// assert_eq!(above_exset.frontier(), 0);
198    ///
199    /// above_exset.add_event(1);
200    /// assert_eq!(above_exset.frontier(), 1);
201    ///
202    /// above_exset.add_event(3);
203    /// assert_eq!(above_exset.frontier(), 1);
204    ///
205    /// above_exset.add_event(2);
206    /// assert_eq!(above_exset.frontier(), 3);
207    ///
208    /// above_exset.add_event(4);
209    /// assert_eq!(above_exset.frontier(), 4);
210    ///
211    /// above_exset.add_event(6);
212    /// assert_eq!(above_exset.frontier(), 4);
213    /// ```
214    fn frontier(&self) -> u64 {
215        self.max
216    }
217
218    /// Merges `other` `AboveExSet` into `self`.
219    ///
220    /// # Examples
221    /// ```
222    /// use threshold::*;
223    ///
224    /// let mut above_exset = AboveExSet::new();
225    /// above_exset.add_event(1);
226    /// above_exset.add_event(3);
227    /// above_exset.add_event(4);
228    /// assert_eq!(above_exset.events(), (1, vec![3, 4]));
229    ///
230    /// above_exset.join(&AboveExSet::from_event(3));
231    /// assert_eq!(above_exset.events(), (1, vec![3, 4]));
232    ///
233    /// above_exset.join(&AboveExSet::from_event(5));
234    /// assert_eq!(above_exset.events(), (1, vec![3, 4, 5]));
235    ///
236    /// let mut other = AboveExSet::new();
237    /// other.add_event(2);
238    /// other.add_event(7);
239    /// above_exset.join(&other);
240    /// assert_eq!(above_exset.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        // add extras higher than `self.max` as extras
247        let max = self.max;
248        other.exs.iter().filter(|ex| **ex > max).for_each(|ex| {
249            self.exs.insert(*ex);
250        });
251
252        // maybe compress
253        self.try_compress();
254    }
255
256    fn meet(&mut self, other: &Self) {
257        // the new max value is the min of both max values
258        let previous_max = self.max;
259        self.max = cmp::min(self.max, other.max);
260
261        // keep as extras only those that are extras in `other` or are below
262        // `other.max`
263        self.exs
264            .retain(|ex| ex <= &other.max || other.exs.contains(ex));
265
266        // add as extras what's in between new max and previous max that is an
267        // extra in `other`
268        self.exs.extend(
269            ((self.max + 1)..=previous_max).filter(|ex| other.exs.contains(ex)),
270        );
271
272        // maybe compress
273        self.try_compress();
274    }
275
276    fn subtracted(&self, other: &Self) -> Vec<u64> {
277        //include only extras that are not events in `other`
278        let iter = self.exs.iter().filter(|ex| !other.is_event(**ex)).cloned();
279        if self.max > other.max {
280            iter.chain(
281                ((other.max + 1)..=self.max)
282                    .filter(|event| !other.exs.contains(event)),
283            )
284            .collect()
285        } else {
286            iter.collect()
287        }
288    }
289
290    /// Returns a `AboveExSet` event iterator with all events from lowest to
291    /// highest.
292    ///
293    /// # Examples
294    /// ```
295    /// use threshold::*;
296    ///
297    /// let mut above_exset = AboveExSet::new();
298    /// above_exset.add_event(3);
299    /// above_exset.add_event(5);
300    ///
301    /// let mut iter = above_exset.event_iter();
302    /// assert_eq!(iter.next(), Some(3));
303    /// assert_eq!(iter.next(), Some(5));
304    /// assert_eq!(iter.next(), None);
305    /// ```
306    fn event_iter(self) -> Self::EventIter {
307        EventIter {
308            current: 0,
309            max: self.max,
310            exs: BTreeSet::from_iter(self.exs).into_iter(),
311        }
312    }
313}
314
315impl AboveExSet {
316    /// Tries to set a new max contiguous event.
317    fn try_compress(&mut self) {
318        // only keep in extras those that can't be compressed
319        while self.exs.remove(&(self.max + 1)) {
320            self.max = self.max + 1;
321        }
322    }
323
324    /// Creates a new instance from the highest contiguous event, and a sequence
325    /// of extra events.
326    ///
327    /// # Examples
328    /// ```
329    /// use threshold::*;
330    ///
331    /// let above_exset = AboveExSet::from(0, vec![2, 4, 5]);
332    /// assert!(!above_exset.is_event(1));
333    /// assert!(above_exset.is_event(2));
334    /// assert!(!above_exset.is_event(3));
335    /// assert!(above_exset.is_event(4));
336    /// assert!(above_exset.is_event(5));
337    /// assert!(!above_exset.is_event(6));
338    /// ```
339    pub fn from<I: IntoIterator<Item = u64>>(max: u64, iter: I) -> Self {
340        AboveExSet {
341            max,
342            exs: HashSet::from_iter(iter),
343        }
344    }
345
346    /// Returns a set of events that: 1) are below `ceil` (not including ceil)
347    /// and 2) are not part of `AboveExSet`.
348    pub fn missing_below(&self, ceil: u64) -> impl Iterator<Item = u64> + '_ {
349        let below = (self.max + 1)..ceil;
350        // only keep as events those that are not in the extras
351        below.filter(move |event| !self.exs.contains(event))
352    }
353}
354
355pub struct EventIter {
356    // Last contiguous value returned by the iterator
357    current: u64,
358    // Last contiguous value that should be returned by the iterator
359    max: u64,
360    // Iterator of extras
361    exs: btree_set::IntoIter<u64>,
362}
363
364impl Iterator for EventIter {
365    type Item = u64;
366
367    fn next(&mut self) -> Option<Self::Item> {
368        if self.current == self.max {
369            // we've reached the last contiguous, just call next on the extras
370            // iterator
371            self.exs.next()
372        } else {
373            // compute next value
374            self.current += 1;
375            Some(self.current)
376        }
377    }
378}
379
380impl fmt::Debug for AboveExSet {
381    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382        if self.exs.is_empty() {
383            write!(f, "{}", self.max)
384        } else {
385            let exs: std::collections::BTreeSet<_> = self.exs.iter().collect();
386            write!(f, "({} + {:?})", self.max, exs)
387        }
388    }
389}