use std::collections::HashMap;
use super::lru::Entry;
#[derive(Debug, Default)]
pub(super) struct LruList {
pub(super) most_recent: Option<String>,
pub(super) least_recent: Option<String>,
}
impl LruList {
pub(super) fn insert_most_recent(
&mut self,
entries: &mut HashMap<String, Entry>,
key: String,
mut entry: Entry,
) {
let old_head = self.most_recent.clone();
entry.previous = None;
entry.next = old_head.clone();
entries.insert(key.clone(), entry);
if let Some(head) = old_head {
if let Some(head_entry) = entries.get_mut(&head) {
head_entry.previous = Some(key.clone());
}
} else {
self.least_recent = Some(key.clone());
}
self.most_recent = Some(key);
}
pub(super) fn move_to_most_recent(&mut self, entries: &mut HashMap<String, Entry>, key: &str) {
if self.most_recent.as_deref() == Some(key) || !entries.contains_key(key) {
return;
}
let key = key.to_string();
self.detach_existing(entries, &key);
let old_head = self.most_recent.clone();
if let Some(entry) = entries.get_mut(&key) {
entry.previous = None;
entry.next = old_head.clone();
}
if let Some(head) = old_head {
if let Some(head_entry) = entries.get_mut(&head) {
head_entry.previous = Some(key.clone());
}
} else {
self.least_recent = Some(key.clone());
}
self.most_recent = Some(key);
}
pub(super) fn remove_entry(
&mut self,
entries: &mut HashMap<String, Entry>,
key: &str,
) -> Option<Entry> {
if !entries.contains_key(key) {
return None;
}
self.detach_existing(entries, key);
entries.remove(key)
}
fn detach_existing(&mut self, entries: &mut HashMap<String, Entry>, key: &str) {
let Some((previous, next)) = entries
.get(key)
.map(|entry| (entry.previous.clone(), entry.next.clone()))
else {
return;
};
if let Some(previous_key) = &previous {
if let Some(previous_entry) = entries.get_mut(previous_key) {
previous_entry.next = next.clone();
}
} else {
self.most_recent = next.clone();
}
if let Some(next_key) = &next {
if let Some(next_entry) = entries.get_mut(next_key) {
next_entry.previous = previous.clone();
}
} else {
self.least_recent = previous.clone();
}
if let Some(entry) = entries.get_mut(key) {
entry.previous = None;
entry.next = None;
}
}
}