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}