use std::collections::BTreeMap;
#[derive(Debug, Clone)]
struct RangeContainer<V> {
low: i32,
high: i32,
value: V,
}
#[derive(Debug, Clone, Default)]
pub struct RangeMap<V> {
tree: BTreeMap<i32, RangeContainer<V>>,
}
impl<V: Clone + PartialEq> RangeMap<V> {
pub fn new() -> Self {
Self {
tree: BTreeMap::new(),
}
}
pub fn add_range(&mut self, low: i32, high: i32, value: V) -> Result<(), String> {
if low > high {
return Err(format!("low {low} > high {high}"));
}
self.tree.insert(low, RangeContainer { low, high, value });
Ok(())
}
pub fn get(&self, key: i32) -> Option<&V> {
let entry = self.tree.range(..=key).next_back()?;
let rc = entry.1;
if key <= rc.high {
Some(&rc.value)
} else {
None
}
}
pub fn remove(&mut self, value: &V) -> bool {
let key = self
.tree
.iter()
.find(|(_, rc)| &rc.value == value)
.map(|(k, _)| *k);
if let Some(k) = key {
self.tree.remove(&k);
true
} else {
false
}
}
pub fn lower_bound(&self, key: i32) -> Option<i32> {
self.tree.range(..=key).next_back().map(|(_, rc)| rc.low)
}
pub fn len(&self) -> usize {
self.tree.len()
}
pub fn is_empty(&self) -> bool {
self.tree.is_empty()
}
pub fn clear(&mut self) {
self.tree.clear();
}
}