ezno_checker/utilities/
range_map.rs1use std::collections::BTreeMap;
2use std::fmt::Debug;
3use std::ops::Range;
4
5#[derive(Debug)]
6pub struct RangeMap<T> {
7 entries: BTreeMap<u32, Vec<(u32, T)>>,
9}
10
11impl<T> Default for RangeMap<T> {
12 fn default() -> Self {
13 Self { entries: BTreeMap::default() }
14 }
15}
16
17impl<T> RangeMap<T> {
18 #[must_use]
19 pub fn new() -> Self {
20 Self { entries: Default::default() }
21 }
22
23 pub fn push(&mut self, range: impl Into<Range<u32>>, item: T) {
24 let range = range.into();
25 if let Some(existing) = self.entries.get_mut(&range.start) {
26 existing.push((range.end, item));
27 } else {
28 self.entries.insert(range.start, vec![(range.end, item)]);
29 }
30 }
31
32 #[must_use]
34 pub fn get(&self, point: u32) -> Option<&T> {
35 self.get_with_range(point).map(|(res, _)| res)
36 }
37
38 #[must_use]
39 pub fn get_with_range(&self, point: u32) -> Option<(&T, Range<u32>)> {
40 self.entries
41 .range(0..=point)
42 .rev()
44 .find_map(|(s, v)| v.iter().find_map(|(e, v)| (*e > point).then_some((v, (*s..*e)))))
45 }
46
47 pub fn get_many(&self, point: u32, cb: impl for<'a> Fn(&'a T)) {
49 let rev = &mut self
50 .entries
51 .range(0..=point)
52 .rev();
54
55 for (start, values) in rev {
56 debug_assert!(*start <= point);
57 for (end, value) in values {
58 if point <= *end {
59 cb(value);
60 }
61 }
62 }
63 }
64
65 pub fn get_exact(&self, range: impl Into<Range<u32>>) -> Option<&T> {
67 let range = range.into();
68 self.entries
69 .get(&range.start)
70 .and_then(|v| v.iter().find_map(|(e, v)| (*e == range.end).then_some(v)))
71 }
72}