#[allow(clippy::wildcard_imports)]
use super::*;
impl PageEntry {
#[must_use]
pub(crate) fn new(offset: u64, size: usize) -> Self {
Self {
offset,
size,
access_count: 0,
last_access: 0,
}
}
pub(crate) fn touch(&mut self, timestamp: u64) {
self.access_count += 1;
self.last_access = timestamp;
}
}
#[derive(Debug, Default)]
pub(crate) struct PageTable {
pages: std::collections::HashMap<u64, PageEntry>,
timestamp: u64,
}
impl PageTable {
#[must_use]
pub(crate) fn new() -> Self {
Self::default()
}
pub(crate) fn add_page(&mut self, offset: u64, size: usize) {
let mut entry = PageEntry::new(offset, size);
entry.touch(self.next_timestamp());
self.pages.insert(offset, entry);
}
pub(crate) fn touch(&mut self, offset: u64) {
let timestamp = self.next_timestamp();
if let Some(entry) = self.pages.get_mut(&offset) {
entry.touch(timestamp);
}
}
#[must_use]
#[allow(dead_code)]
pub(crate) fn lru_page(&self) -> Option<u64> {
self.pages
.iter()
.min_by_key(|(_, entry)| entry.last_access)
.map(|(&offset, _)| offset)
}
#[must_use]
pub(crate) fn lfu_page(&self) -> Option<u64> {
self.pages
.iter()
.min_by_key(|(_, entry)| entry.access_count)
.map(|(&offset, _)| offset)
}
pub(crate) fn remove(&mut self, offset: u64) -> Option<PageEntry> {
self.pages.remove(&offset)
}
#[must_use]
#[allow(dead_code)]
pub(crate) fn get(&self, offset: u64) -> Option<&PageEntry> {
self.pages.get(&offset)
}
#[must_use]
#[allow(dead_code)]
pub(crate) fn len(&self) -> usize {
self.pages.len()
}
#[must_use]
#[allow(dead_code)]
pub(crate) fn is_empty(&self) -> bool {
self.pages.is_empty()
}
#[must_use]
#[allow(dead_code)]
pub(crate) fn total_size(&self) -> usize {
self.pages.values().map(|p| p.size).sum()
}
fn next_timestamp(&mut self) -> u64 {
self.timestamp += 1;
self.timestamp
}
}