Skip to content

Commit

Permalink
make eviction logic deterministic by using indexset
Browse files Browse the repository at this point in the history
  • Loading branch information
jauhararifin committed Dec 25, 2024
1 parent c54391f commit 3b26411
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions src/pager/evictor.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
use anyhow::anyhow;
use std::collections::HashSet;
use indexmap::IndexSet;

pub(crate) struct Evictor {
ref_count: Vec<usize>,
free_frames: HashSet<usize>,
free_and_clean: HashSet<usize>,
// It is important to use IndexSet and not HashSet to make it deterministic
free_frames: IndexSet<usize>,
free_and_clean: IndexSet<usize>,
}

impl Evictor {
pub(crate) fn new(n: usize) -> Self {
Self {
ref_count: vec![0; n],
free_frames: HashSet::default(),
free_and_clean: HashSet::default(),
free_frames: IndexSet::default(),
free_and_clean: IndexSet::default(),
}
}

pub(crate) fn acquired(&mut self, frame_id: usize) {
log::trace!("acquired frame_id={frame_id}");
assert!(frame_id < self.ref_count.len());
self.ref_count[frame_id] += 1;
self.free_frames.remove(&frame_id);
self.free_and_clean.remove(&frame_id);
self.free_frames.swap_remove(&frame_id);
self.free_and_clean.swap_remove(&frame_id);
}

pub(crate) fn released(&mut self, frame_id: usize, dirty: bool) {
Expand All @@ -34,7 +35,7 @@ impl Evictor {
}

if dirty {
self.free_and_clean.remove(&frame_id);
self.free_and_clean.swap_remove(&frame_id);
}

if !dirty && free {
Expand All @@ -51,12 +52,12 @@ impl Evictor {

if let Some(frame_id) = self.free_and_clean.iter().next().copied() {
self.ref_count[frame_id] = 1;
self.free_and_clean.remove(&frame_id);
self.free_frames.remove(&frame_id);
self.free_and_clean.swap_remove(&frame_id);
self.free_frames.swap_remove(&frame_id);
Ok((frame_id, false))
} else if let Some(frame_id) = self.free_frames.iter().next().copied() {
self.ref_count[frame_id] = 1;
self.free_frames.remove(&frame_id);
self.free_frames.swap_remove(&frame_id);
Ok((frame_id, true))
} else {
return Err(anyhow!("all pages are pinned"));
Expand Down

0 comments on commit 3b26411

Please sign in to comment.