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}