Skip to content

Commit f9ac2f9

Browse files
authored
refactor: wrapper no/immutable/mutable op into Op (#788)
Signed-off-by: MrCroxx <[email protected]>
1 parent d633ae2 commit f9ac2f9

File tree

8 files changed

+226
-230
lines changed

8 files changed

+226
-230
lines changed

foyer-memory/src/eviction/fifo.rs

+9-25
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use foyer_common::code::{Key, Value};
1818
use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListAtomicLink};
1919
use serde::{Deserialize, Serialize};
2020

21-
use super::{Eviction, Operator};
21+
use super::{Eviction, Op};
2222
use crate::record::{CacheHint, Record};
2323

2424
/// Fifo eviction algorithm config.
@@ -93,28 +93,12 @@ where
9393
record.set_in_eviction(false);
9494
}
9595

96-
fn acquire_operator() -> super::Operator {
97-
Operator::Noop
96+
fn acquire() -> Op<Self> {
97+
Op::noop()
9898
}
9999

100-
fn acquire_immutable(&self, _record: &Arc<Record<Self>>) {
101-
unreachable!()
102-
}
103-
104-
fn acquire_mutable(&mut self, _record: &Arc<Record<Self>>) {
105-
unreachable!()
106-
}
107-
108-
fn release_operator() -> super::Operator {
109-
Operator::Noop
110-
}
111-
112-
fn release_immutable(&self, _record: &Arc<Record<Self>>) {
113-
unreachable!()
114-
}
115-
116-
fn release_mutable(&mut self, _record: &Arc<Record<Self>>) {
117-
unreachable!()
100+
fn release() -> Op<Self> {
101+
Op::noop()
118102
}
119103
}
120104

@@ -125,17 +109,17 @@ pub mod tests {
125109

126110
use super::*;
127111
use crate::{
128-
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_eq, TestEviction},
112+
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_eq, Dump},
129113
record::Data,
130114
};
131115

132-
impl<K, V> TestEviction for Fifo<K, V>
116+
impl<K, V> Dump for Fifo<K, V>
133117
where
134118
K: Key + Clone,
135119
V: Value + Clone,
136120
{
137-
type Dump = Vec<Arc<Record<Self>>>;
138-
fn dump(&self) -> Self::Dump {
121+
type Output = Vec<Arc<Record<Self>>>;
122+
fn dump(&self) -> Self::Output {
139123
let mut res = vec![];
140124
let mut cursor = self.queue.cursor();
141125
loop {

foyer-memory/src/eviction/lfu.rs

+47-62
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use foyer_common::{
2222
use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListAtomicLink};
2323
use serde::{Deserialize, Serialize};
2424

25-
use super::{Eviction, Operator};
25+
use super::{Eviction, Op};
2626
use crate::record::{CacheHint, Record};
2727

2828
/// w-TinyLFU eviction algorithm config.
@@ -347,71 +347,56 @@ where
347347
}
348348
}
349349

350-
fn acquire_operator() -> super::Operator {
351-
// TODO(MrCroxx): use a count-min-sketch with atomic u16 impl.
352-
Operator::Mutable
353-
}
354-
355-
fn acquire_immutable(&self, _record: &Arc<Record<Self>>) {
356-
unreachable!()
357-
}
358-
359-
fn acquire_mutable(&mut self, record: &Arc<Record<Self>>) {
360-
// Update frequency by access.
361-
self.update_frequencies(record.hash());
350+
fn acquire() -> Op<Self> {
351+
Op::mutable(|this: &mut Self, record| {
352+
// Update frequency by access.
353+
this.update_frequencies(record.hash());
362354

363-
if !record.is_in_eviction() {
364-
return;
365-
}
355+
if !record.is_in_eviction() {
356+
return;
357+
}
366358

367-
let state = unsafe { &mut *record.state().get() };
359+
let state = unsafe { &mut *record.state().get() };
368360

369-
strict_assert!(state.link.is_linked());
361+
strict_assert!(state.link.is_linked());
370362

371-
match state.queue {
372-
Queue::None => unreachable!(),
373-
Queue::Window => {
374-
// Move to MRU position of `window`.
375-
let r = unsafe { self.window.remove_from_ptr(Arc::as_ptr(record)) };
376-
self.window.push_back(r);
377-
}
378-
Queue::Probation => {
379-
// Promote to MRU position of `protected`.
380-
let r = unsafe { self.probation.remove_from_ptr(Arc::as_ptr(record)) };
381-
self.decrease_queue_weight(Queue::Probation, record.weight());
382-
state.queue = Queue::Protected;
383-
self.increase_queue_weight(Queue::Protected, record.weight());
384-
self.protected.push_back(r);
385-
386-
// If `protected` weight exceeds the capacity, overflow entry from `protected` to `probation`.
387-
while self.protected_weight > self.protected_weight_capacity {
388-
strict_assert!(!self.protected.is_empty());
389-
let r = self.protected.pop_front().unwrap();
390-
let s = unsafe { &mut *r.state().get() };
391-
self.decrease_queue_weight(Queue::Protected, r.weight());
392-
s.queue = Queue::Probation;
393-
self.increase_queue_weight(Queue::Probation, r.weight());
394-
self.probation.push_back(r);
363+
match state.queue {
364+
Queue::None => unreachable!(),
365+
Queue::Window => {
366+
// Move to MRU position of `window`.
367+
let r = unsafe { this.window.remove_from_ptr(Arc::as_ptr(record)) };
368+
this.window.push_back(r);
369+
}
370+
Queue::Probation => {
371+
// Promote to MRU position of `protected`.
372+
let r = unsafe { this.probation.remove_from_ptr(Arc::as_ptr(record)) };
373+
this.decrease_queue_weight(Queue::Probation, record.weight());
374+
state.queue = Queue::Protected;
375+
this.increase_queue_weight(Queue::Protected, record.weight());
376+
this.protected.push_back(r);
377+
378+
// If `protected` weight exceeds the capacity, overflow entry from `protected` to `probation`.
379+
while this.protected_weight > this.protected_weight_capacity {
380+
strict_assert!(!this.protected.is_empty());
381+
let r = this.protected.pop_front().unwrap();
382+
let s = unsafe { &mut *r.state().get() };
383+
this.decrease_queue_weight(Queue::Protected, r.weight());
384+
s.queue = Queue::Probation;
385+
this.increase_queue_weight(Queue::Probation, r.weight());
386+
this.probation.push_back(r);
387+
}
388+
}
389+
Queue::Protected => {
390+
// Move to MRU position of `protected`.
391+
let r = unsafe { this.protected.remove_from_ptr(Arc::as_ptr(record)) };
392+
this.protected.push_back(r);
395393
}
396394
}
397-
Queue::Protected => {
398-
// Move to MRU position of `protected`.
399-
let r = unsafe { self.protected.remove_from_ptr(Arc::as_ptr(record)) };
400-
self.protected.push_back(r);
401-
}
402-
}
403-
}
404-
405-
fn release_operator() -> Operator {
406-
Operator::Noop
407-
}
408-
409-
fn release_immutable(&self, _record: &Arc<Record<Self>>) {
410-
unreachable!()
395+
})
411396
}
412397

413-
fn release_mutable(&mut self, _record: &Arc<Record<Self>>) {
414-
unreachable!()
398+
fn release() -> Op<Self> {
399+
Op::noop()
415400
}
416401
}
417402

@@ -422,17 +407,17 @@ mod tests {
422407

423408
use super::*;
424409
use crate::{
425-
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_vec_eq, TestEviction},
410+
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_vec_eq, Dump, OpExt},
426411
record::Data,
427412
};
428413

429-
impl<K, V> TestEviction for Lfu<K, V>
414+
impl<K, V> Dump for Lfu<K, V>
430415
where
431416
K: Key + Clone,
432417
V: Value + Clone,
433418
{
434-
type Dump = Vec<Vec<Arc<Record<Self>>>>;
435-
fn dump(&self) -> Self::Dump {
419+
type Output = Vec<Vec<Arc<Record<Self>>>>;
420+
fn dump(&self) -> Self::Output {
436421
let mut window = vec![];
437422
let mut probation = vec![];
438423
let mut protected = vec![];

foyer-memory/src/eviction/lru.rs

+43-55
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use foyer_common::{
2121
use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListAtomicLink};
2222
use serde::{Deserialize, Serialize};
2323

24-
use super::{Eviction, Operator};
24+
use super::{Eviction, Op};
2525
use crate::record::{CacheHint, Record};
2626

2727
/// Lru eviction algorithm config.
@@ -248,70 +248,58 @@ where
248248
assert_eq!(self.high_priority_weight, 0);
249249
}
250250

251-
fn acquire_operator() -> super::Operator {
252-
Operator::Mutable
253-
}
254-
255-
fn acquire_immutable(&self, _record: &Arc<Record<Self>>) {
256-
unreachable!()
257-
}
258-
259-
fn acquire_mutable(&mut self, record: &Arc<Record<Self>>) {
260-
if !record.is_in_eviction() {
261-
return;
262-
}
263-
264-
let state = unsafe { &mut *record.state().get() };
265-
assert!(state.link.is_linked());
251+
fn acquire() -> Op<Self> {
252+
Op::mutable(|this: &mut Self, record| {
253+
if !record.is_in_eviction() {
254+
return;
255+
}
266256

267-
if state.is_pinned {
268-
return;
269-
}
257+
let state = unsafe { &mut *record.state().get() };
258+
assert!(state.link.is_linked());
270259

271-
// Pin the record by moving it to the pin list.
260+
if state.is_pinned {
261+
return;
262+
}
272263

273-
let r = if state.in_high_priority_pool {
274-
unsafe { self.high_priority_list.remove_from_ptr(Arc::as_ptr(record)) }
275-
} else {
276-
unsafe { self.list.remove_from_ptr(Arc::as_ptr(record)) }
277-
};
264+
// Pin the record by moving it to the pin list.
278265

279-
self.pin_list.push_back(r);
266+
let r = if state.in_high_priority_pool {
267+
unsafe { this.high_priority_list.remove_from_ptr(Arc::as_ptr(record)) }
268+
} else {
269+
unsafe { this.list.remove_from_ptr(Arc::as_ptr(record)) }
270+
};
280271

281-
state.is_pinned = true;
282-
}
272+
this.pin_list.push_back(r);
283273

284-
fn release_operator() -> Operator {
285-
Operator::Mutable
274+
state.is_pinned = true;
275+
})
286276
}
287277

288-
fn release_immutable(&self, _record: &Arc<Record<Self>>) {
289-
unreachable!()
290-
}
291-
292-
fn release_mutable(&mut self, record: &Arc<Record<Self>>) {
293-
if !record.is_in_eviction() {
294-
return;
295-
}
278+
fn release() -> Op<Self> {
279+
Op::mutable(|this: &mut Self, record| {
280+
if !record.is_in_eviction() {
281+
return;
282+
}
296283

297-
let state = unsafe { &mut *record.state().get() };
298-
assert!(state.link.is_linked());
284+
let state = unsafe { &mut *record.state().get() };
285+
assert!(state.link.is_linked());
299286

300-
if !state.is_pinned {
301-
return;
302-
}
287+
if !state.is_pinned {
288+
return;
289+
}
303290

304-
// Unpin the record by moving it from the pin list.
291+
// Unpin the record by moving it from the pin list.
305292

306-
unsafe { self.pin_list.remove_from_ptr(Arc::as_ptr(record)) };
293+
unsafe { this.pin_list.remove_from_ptr(Arc::as_ptr(record)) };
307294

308-
if state.in_high_priority_pool {
309-
self.high_priority_list.push_back(record.clone());
310-
} else {
311-
self.list.push_back(record.clone());
312-
}
295+
if state.in_high_priority_pool {
296+
this.high_priority_list.push_back(record.clone());
297+
} else {
298+
this.list.push_back(record.clone());
299+
}
313300

314-
state.is_pinned = false;
301+
state.is_pinned = false;
302+
})
315303
}
316304
}
317305

@@ -322,17 +310,17 @@ pub mod tests {
322310

323311
use super::*;
324312
use crate::{
325-
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_vec_eq, TestEviction},
313+
eviction::test_utils::{assert_ptr_eq, assert_ptr_vec_vec_eq, Dump, OpExt},
326314
record::Data,
327315
};
328316

329-
impl<K, V> TestEviction for Lru<K, V>
317+
impl<K, V> Dump for Lru<K, V>
330318
where
331319
K: Key + Clone,
332320
V: Value + Clone,
333321
{
334-
type Dump = Vec<Vec<Arc<Record<Self>>>>;
335-
fn dump(&self) -> Self::Dump {
322+
type Output = Vec<Vec<Arc<Record<Self>>>>;
323+
fn dump(&self) -> Self::Output {
336324
let mut low = vec![];
337325
let mut high = vec![];
338326
let mut pin = vec![];

0 commit comments

Comments
 (0)