Skip to content

Commit

Permalink
fix: assert handle weight and refactor handle (#380)
Browse files Browse the repository at this point in the history
* fix: assert handle weight and refactor handle

Signed-off-by: MrCroxx <mrcroxx@outlook.com>

* chore: rename charge to weight

Signed-off-by: MrCroxx <mrcroxx@outlook.com>

---------

Signed-off-by: MrCroxx <mrcroxx@outlook.com>
  • Loading branch information
MrCroxx authored Apr 20, 2024
1 parent cbedab1 commit c51d248
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 158 deletions.
10 changes: 5 additions & 5 deletions foyer-memory/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ where
}
}

pub fn charge(&self) -> usize {
pub fn weight(&self) -> usize {
match self {
CacheEntry::Fifo(entry) => entry.charge(),
CacheEntry::Lru(entry) => entry.charge(),
CacheEntry::Lfu(entry) => entry.charge(),
CacheEntry::S3Fifo(entry) => entry.charge(),
CacheEntry::Fifo(entry) => entry.weight(),
CacheEntry::Lru(entry) => entry.weight(),
CacheEntry::Lfu(entry) => entry.weight(),
CacheEntry::S3Fifo(entry) => entry.weight(),
}
}

Expand Down
21 changes: 11 additions & 10 deletions foyer-memory/src/eviction/fifo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,24 @@ where

intrusive_adapter! { FifoHandleDlistAdapter<T> = NonNull<FifoHandle<T>>: FifoHandle<T> { link: DlistLink } where T: Send + Sync + 'static }

impl<T> Handle for FifoHandle<T>
impl<T> Default for FifoHandle<T>
where
T: Send + Sync + 'static,
{
type Data = T;
type Context = FifoContext;

fn new() -> Self {
fn default() -> Self {
Self {
link: DlistLink::default(),
base: BaseHandle::new(),
}
}
}

fn init(&mut self, hash: u64, data: Self::Data, charge: usize, context: Self::Context) {
self.base.init(hash, data, charge, context);
}
impl<T> Handle for FifoHandle<T>
where
T: Send + Sync + 'static,
{
type Data = T;
type Context = FifoContext;

fn base(&self) -> &BaseHandle<Self::Data, Self::Context> {
&self.base
Expand Down Expand Up @@ -159,7 +160,7 @@ pub mod tests {
use itertools::Itertools;

use super::*;
use crate::eviction::test_utils::TestEviction;
use crate::{eviction::test_utils::TestEviction, handle::HandleExt};

impl<T> TestEviction for Fifo<T>
where
Expand All @@ -177,7 +178,7 @@ pub mod tests {
type TestFifo = Fifo<u64>;

unsafe fn new_test_fifo_handle_ptr(data: u64) -> NonNull<TestFifoHandle> {
let mut handle = Box::new(TestFifoHandle::new());
let mut handle = Box::<TestFifoHandle>::default();
handle.init(0, data, 1, FifoContext);
NonNull::new_unchecked(Box::into_raw(handle))
}
Expand Down
101 changes: 51 additions & 50 deletions foyer-memory/src/eviction/lfu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,24 +88,25 @@ where

intrusive_adapter! { LfuHandleDlistAdapter<T> = NonNull<LfuHandle<T>>: LfuHandle<T> { link: DlistLink } where T: Send + Sync + 'static }

impl<T> Handle for LfuHandle<T>
impl<T> Default for LfuHandle<T>
where
T: Send + Sync + 'static,
{
type Data = T;
type Context = LfuContext;

fn new() -> Self {
fn default() -> Self {
Self {
link: DlistLink::default(),
base: BaseHandle::new(),
queue: Queue::None,
}
}
}

fn init(&mut self, hash: u64, data: Self::Data, charge: usize, context: Self::Context) {
self.base.init(hash, data, charge, context)
}
impl<T> Handle for LfuHandle<T>
where
T: Send + Sync + 'static,
{
type Data = T;
type Context = LfuContext;

fn base(&self) -> &BaseHandle<Self::Data, Self::Context> {
&self.base
Expand Down Expand Up @@ -139,12 +140,12 @@ where
probation: Dlist<LfuHandleDlistAdapter<T>>,
protected: Dlist<LfuHandleDlistAdapter<T>>,

window_charges: usize,
probation_charges: usize,
protected_charges: usize,
window_weight: usize,
probation_weight: usize,
protected_weight: usize,

window_charges_capacity: usize,
protected_charges_capacity: usize,
window_weight_capacity: usize,
protected_weight_capacity: usize,

frequencies: CMSketchU16,

Expand All @@ -156,23 +157,23 @@ impl<T> Lfu<T>
where
T: Send + Sync + 'static,
{
fn increase_queue_charges(&mut self, handle: &LfuHandle<T>) {
let charges = handle.base().charge();
fn increase_queue_weight(&mut self, handle: &LfuHandle<T>) {
let weight = handle.base().weight();
match handle.queue {
Queue::None => unreachable!(),
Queue::Window => self.window_charges += charges,
Queue::Probation => self.probation_charges += charges,
Queue::Protected => self.protected_charges += charges,
Queue::Window => self.window_weight += weight,
Queue::Probation => self.probation_weight += weight,
Queue::Protected => self.protected_weight += weight,
}
}

fn decrease_queue_charges(&mut self, handle: &LfuHandle<T>) {
let charges = handle.base().charge();
fn decrease_queue_weight(&mut self, handle: &LfuHandle<T>) {
let weight = handle.base().weight();
match handle.queue {
Queue::None => unreachable!(),
Queue::Window => self.window_charges -= charges,
Queue::Probation => self.probation_charges -= charges,
Queue::Protected => self.protected_charges -= charges,
Queue::Window => self.window_weight -= weight,
Queue::Probation => self.probation_weight -= weight,
Queue::Protected => self.protected_weight -= weight,
}
}

Expand Down Expand Up @@ -215,20 +216,20 @@ where
config.window_capacity_ratio + config.protected_capacity_ratio
);

let window_charges_capacity = (capacity as f64 * config.window_capacity_ratio) as usize;
let protected_charges_capacity = (capacity as f64 * config.protected_capacity_ratio) as usize;
let window_weight_capacity = (capacity as f64 * config.window_capacity_ratio) as usize;
let protected_weight_capacity = (capacity as f64 * config.protected_capacity_ratio) as usize;
let frequencies = CMSketchU16::new(config.cmsketch_eps, config.cmsketch_confidence);
let decay = frequencies.width();

Self {
window: Dlist::new(),
probation: Dlist::new(),
protected: Dlist::new(),
window_charges: 0,
probation_charges: 0,
protected_charges: 0,
window_charges_capacity,
protected_charges_capacity,
window_weight: 0,
probation_weight: 0,
protected_weight: 0,
window_weight_capacity,
protected_weight_capacity,
frequencies,
step: 0,
decay,
Expand All @@ -246,17 +247,17 @@ where
handle.base_mut().set_in_eviction(true);
handle.queue = Queue::Window;

self.increase_queue_charges(handle);
self.increase_queue_weight(handle);
self.update_frequencies(handle.base().hash());

// If `window` charges exceeds the capacity, overflow entry from `window` to `probation`.
while self.window_charges > self.window_charges_capacity {
// If `window` weight exceeds the capacity, overflow entry from `window` to `probation`.
while self.window_weight > self.window_weight_capacity {
debug_assert!(!self.window.is_empty());
let mut ptr = self.window.pop_front().unwrap_unchecked();
let handle = ptr.as_mut();
self.decrease_queue_charges(handle);
self.decrease_queue_weight(handle);
handle.queue = Queue::Probation;
self.increase_queue_charges(handle);
self.increase_queue_weight(handle);
self.probation.push_back(ptr);
}
}
Expand Down Expand Up @@ -288,7 +289,7 @@ where
debug_assert!(handle.base().is_in_eviction());
debug_assert_ne!(handle.queue, Queue::None);

self.decrease_queue_charges(handle);
self.decrease_queue_weight(handle);
handle.queue = Queue::None;
handle.base_mut().set_in_eviction(false);

Expand Down Expand Up @@ -318,19 +319,19 @@ where
debug_assert!(handle.link.is_linked());
debug_assert!(handle.base().is_in_eviction());
self.probation.remove_raw(handle.link.raw());
self.decrease_queue_charges(handle);
self.decrease_queue_weight(handle);
handle.queue = Queue::Protected;
self.increase_queue_charges(handle);
self.increase_queue_weight(handle);
self.protected.push_back(ptr);

// If `protected` charges exceeds the capacity, overflow entry from `protected` to `probation`.
while self.protected_charges > self.protected_charges_capacity {
// If `protected` weight exceeds the capacity, overflow entry from `protected` to `probation`.
while self.protected_weight > self.protected_weight_capacity {
debug_assert!(!self.protected.is_empty());
let mut ptr = self.protected.pop_front().unwrap_unchecked();
let handle = ptr.as_mut();
self.decrease_queue_charges(handle);
self.decrease_queue_weight(handle);
handle.queue = Queue::Probation;
self.increase_queue_charges(handle);
self.increase_queue_weight(handle);
self.probation.push_back(ptr);
}
}
Expand Down Expand Up @@ -364,7 +365,7 @@ where

debug_assert!(!handle.link.is_linked());

self.decrease_queue_charges(handle);
self.decrease_queue_weight(handle);
handle.queue = Queue::None;
handle.base_mut().set_in_eviction(false);
}
Expand Down Expand Up @@ -401,7 +402,7 @@ mod tests {
use itertools::Itertools;

use super::*;
use crate::eviction::test_utils::TestEviction;
use crate::{eviction::test_utils::TestEviction, handle::HandleExt};

impl<T> TestEviction for Lfu<T>
where
Expand Down Expand Up @@ -432,9 +433,9 @@ mod tests {
assert_eq!(lfu.window.len(), window);
assert_eq!(lfu.probation.len(), probation);
assert_eq!(lfu.protected.len(), protected);
assert_eq!(lfu.window_charges, window);
assert_eq!(lfu.probation_charges, probation);
assert_eq!(lfu.protected_charges, protected);
assert_eq!(lfu.window_weight, window);
assert_eq!(lfu.probation_weight, probation);
assert_eq!(lfu.protected_weight, protected);
let es = lfu.dump().into_iter().collect_vec();
assert_eq!(es, entries);
}
Expand All @@ -449,7 +450,7 @@ mod tests {
unsafe {
let ptrs = (0..100)
.map(|i| {
let mut handle = Box::new(TestLfuHandle::new());
let mut handle = Box::<TestLfuHandle>::default();
handle.init(i, i, 1, LfuContext);
NonNull::new_unchecked(Box::into_raw(handle))
})
Expand All @@ -464,8 +465,8 @@ mod tests {
};
let mut lfu = TestLfu::new(10, &config);

assert_eq!(lfu.window_charges_capacity, 2);
assert_eq!(lfu.protected_charges_capacity, 6);
assert_eq!(lfu.window_weight_capacity, 2);
assert_eq!(lfu.protected_weight_capacity, 6);

lfu.push(ptrs[0]);
lfu.push(ptrs[1]);
Expand Down
Loading

0 comments on commit c51d248

Please sign in to comment.