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}