pingora_cache/eviction/mod.rs
1// Copyright 2025 Cloudflare, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Cache eviction module
16
17use crate::key::CompactCacheKey;
18
19use async_trait::async_trait;
20use pingora_error::Result;
21use std::time::SystemTime;
22
23pub mod lru;
24pub mod simple_lru;
25
26/// The trait that a cache eviction algorithm needs to implement
27///
28/// NOTE: these trait methods require &self not &mut self, which means concurrency should
29/// be handled the implementations internally.
30#[async_trait]
31pub trait EvictionManager: Send + Sync {
32 /// Total size of the cache in bytes tracked by this eviction manager
33 fn total_size(&self) -> usize;
34 /// Number of assets tracked by this eviction manager
35 fn total_items(&self) -> usize;
36 /// Number of bytes that are already evicted
37 ///
38 /// The accumulated number is returned to play well with Prometheus counter metric type.
39 fn evicted_size(&self) -> usize;
40 /// Number of assets that are already evicted
41 ///
42 /// The accumulated number is returned to play well with Prometheus counter metric type.
43 fn evicted_items(&self) -> usize;
44
45 /// Admit an item
46 ///
47 /// Return one or more items to evict. The sizes of these items are deducted
48 /// from the total size already. The caller needs to make sure that these assets are actually
49 /// removed from the storage.
50 ///
51 /// If the item is already admitted, A. update its freshness; B. if the new size is larger than the
52 /// existing one, Some(_) might be returned for the caller to evict.
53 fn admit(
54 &self,
55 item: CompactCacheKey,
56 size: usize,
57 fresh_until: SystemTime,
58 ) -> Vec<CompactCacheKey>;
59
60 /// Adjust an item's weight upwards by a delta. If the item is not already admitted,
61 /// nothing will happen.
62 ///
63 /// Return one or more items to evict. The sizes of these items are deducted
64 /// from the total size already. The caller needs to make sure that these assets are actually
65 /// removed from the storage.
66 fn increment_weight(&self, item: CompactCacheKey, delta: usize) -> Vec<CompactCacheKey>;
67
68 /// Remove an item from the eviction manager.
69 ///
70 /// The size of the item will be deducted.
71 fn remove(&self, item: &CompactCacheKey);
72
73 /// Access an item that should already be in cache.
74 ///
75 /// If the item is not tracked by this [EvictionManager], track it but no eviction will happen.
76 ///
77 /// The call used for asking the eviction manager to track the assets that are already admitted
78 /// in the cache storage system.
79 fn access(&self, item: &CompactCacheKey, size: usize, fresh_until: SystemTime) -> bool;
80
81 /// Peek into the manager to see if the item is already tracked by the system
82 ///
83 /// This function should have no side-effect on the asset itself. For example, for LRU, this
84 /// method shouldn't change the popularity of the asset being peeked.
85 fn peek(&self, item: &CompactCacheKey) -> bool;
86
87 /// Serialize to save the state of this eviction manager to disk
88 ///
89 /// This function is for preserving the eviction manager's state across server restarts.
90 ///
91 /// `dir_path` define the directory on disk that the data should use.
92 // dir_path is &str no AsRef<Path> so that trait objects can be used
93 async fn save(&self, dir_path: &str) -> Result<()>;
94
95 /// The counterpart of [Self::save()].
96 async fn load(&self, dir_path: &str) -> Result<()>;
97}