decdn_cache/policy/
lru.rs1use super::{
3 AdmissionContext, AdmissionDecision, AdmissionPolicy, EvictionContext, EvictionPlan,
4 EvictionPolicy, Segment,
5};
6use crate::Hash;
7
8#[derive(Debug, Default, Clone, Copy)]
15pub struct LruEviction;
16
17impl EvictionPolicy for LruEviction {
18 fn plan(&self, ctx: &EvictionContext<'_>) -> EvictionPlan {
19 let size = |h: &Hash| ctx.sizes.get(h).copied().unwrap_or(0);
20 let mut ordered: Vec<(Hash, std::time::Instant)> =
21 ctx.candidates.iter().map(|(h, t)| (*h, *t)).collect();
22 ordered.sort_by(|a, b| a.1.cmp(&b.1).then_with(|| size(&b.0).cmp(&size(&a.0))));
24 let mut evict = Vec::new();
25 let mut freed = 0u64;
26 for (h, _) in ordered {
27 if ctx.total_bytes.saturating_sub(freed) <= ctx.target_bytes {
28 break;
29 }
30 if evict.len() as u64 >= ctx.budget {
31 break;
32 }
33 freed = freed.saturating_add(ctx.sizes.get(&h).copied().unwrap_or(0));
34 evict.push(h);
35 }
36 EvictionPlan {
37 evict,
38 promote: Vec::new(),
39 }
40 }
41}
42
43#[derive(Debug, Default, Clone, Copy)]
46pub struct AlwaysAdmit;
47
48impl AdmissionPolicy for AlwaysAdmit {
49 fn admit(&self, _ctx: &AdmissionContext) -> AdmissionDecision {
50 AdmissionDecision::Store {
51 segment: Segment::Main,
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests;