use super::cache::SummaryIndex;
use super::types::{MAX_CACHED_SUMMARIES, SummaryNode, SummaryRange};
impl SummaryIndex {
pub fn insert(&mut self, range: SummaryRange, node: SummaryNode) -> Option<SummaryNode> {
self.touch_lru(range);
let prev = self.tree.insert(range, node);
self.evict_if_over_budget();
prev
}
pub fn append(&mut self, idx: usize) {
let to_drop: Vec<SummaryRange> = self
.tree
.keys()
.filter(|r| r.contains(idx))
.copied()
.collect();
for r in &to_drop {
self.tree.remove(r);
}
self.lru_order.retain(|r| !to_drop.contains(r));
if !to_drop.is_empty() {
self.generation = self.generation.wrapping_add(1);
}
}
pub fn invalidate_after(&mut self, idx: usize) {
let to_drop: Vec<SummaryRange> =
self.tree.keys().filter(|r| r.end > idx).copied().collect();
for r in &to_drop {
self.tree.remove(r);
}
self.lru_order.retain(|r| !to_drop.contains(r));
if !to_drop.is_empty() {
self.generation = self.generation.wrapping_add(1);
}
}
pub(super) fn touch_lru(&mut self, range: SummaryRange) {
self.lru_order.retain(|r| *r != range);
self.lru_order.push(range);
}
fn evict_if_over_budget(&mut self) {
while self.tree.len() > MAX_CACHED_SUMMARIES {
if let Some(oldest) = self.lru_order.first().copied() {
self.tree.remove(&oldest);
self.lru_order.remove(0);
} else {
break;
}
}
}
}