#key-value #cache #eviction #policies #pair #store #manage

sine_cache

SineCache 是一个为 Rust 设计的高性能内存缓存库,旨在高效存储和管理键值对,支持各种驱逐策略。

4 个版本

0.2.0 2024年7月3日
0.1.4 2024年6月29日

#46 in 缓存

Download history 253/week @ 2024-06-25 175/week @ 2024-07-02 12/week @ 2024-07-23

196 每月下载

MIT 许可证

88KB
1.5K SLoC

SineCache

SineCache 是一个为 Rust 设计的高性能内存缓存库,旨在高效存储和管理键值对,支持各种驱逐策略和持久化选项,使用追加只读文件 (AOF)。

功能

强大的缓存机制

SineCache 提供了一个灵活配置和多种驱逐策略支持的强大缓存解决方案,确保适应不同应用程序需求的最优性能。

驱逐策略

从 FIFO(先进先出)、LRU(最近最少使用)和 LFU(最少使用)驱逐策略中选择。此外,通过简单的特质实现定义自定义驱逐策略。

异步支持

  • AsyncCache:将 Cache 结构体包装在 tokio::sync::Mutex 中,通过异步操作(async 版本的 getputremove 等)实现安全的并发访问。

使用追加只读文件 (AOF) 进行持久化

可选地使用 AOF 持久化缓存数据,确保跨应用程序重启恢复缓存状态的可持久性和恢复性。如果提供了 flush_time(毫秒),则数据在每 flush_time 毫秒后将刷新到磁盘(不阻塞主线程)。如果为 None,则每个操作都在相同的线程中刷新到磁盘。

线程安全

通过适当的锁定机制(tokio::sync::Mutex 用于 AsyncCache)确保线程安全,使其适用于多线程环境。

配置灵活性

通过直观的配置结构体(CacheSyncConfigAsyncCacheConfig)配置缓存大小限制、驱逐策略、AOF 设置等。

全面的文档

丰富的API文档和示例简化了应用程序中的集成和定制。

安全性和可靠性

使用Rust的所有权和类型系统构建,确保内存安全,并防止常见的错误,如空指针解引用和数据竞争。

入门指南

要在您的Rust项目中使用SineCache,请将其添加到您的Cargo.toml

[dependencies]
sine_cache = "0.2.0"

示例

以下列出了一些示例,但更详细的文档请访问:https://docs.rs/sine_cache/latest/sine_cache/

Cache - 同步缓存

Cache相关的简单方法。要在并发环境中使用它,可以在Mutex中包装它并使用async方法等进行定制。

use sine_cache::{cache::Cache, config::CacheConfig};

fn main() {
    let capacity = 10; // Maximum number of entries in the cache.
    let mut cache = Cache::new(sine_cache::config::CacheSyncConfig::LFU(CacheConfig{max_size: capacity}));

    // Inserting key-value pairs into the cache
    cache.put(1, "One");
    cache.put(1, "one"); // Overwrites previous value
    cache.put(2, "Two");

    // Retrieving a value from the cache
    let value = cache.get(&1);
    assert!(value.is_some_and(|x| x == &"one"));
}

AsyncCache - 异步缓存

以下列出了一些与AsyncCache相关的示例

  • AOF

    当不需要AOF

use sine_cache::{cache::AsyncCache, config::{AsyncCacheConfig, EvictionAsyncConfig}};

#[tokio::main]
async fn main() {
    let capacity = 10; // Maximum number of entries in the cache.
    let mut cache = AsyncCache::new(AsyncCacheConfig::LFU(EvictionAsyncConfig {max_size: capacity, aof_config: None})).await;

    // Inserting key-value pairs into the cache
    cache.put(1, String::from("One")).await;
    cache.put(1, String::from("one")).await; // Overwrites previous value
    cache.put(2, String::from("Two")).await;

    // Retrieving a value from the cache
    let value = cache.get(&1).await;
    assert!(value.is_some_and(|x| x == "one"));
}
  • AOF

    当需要AOF时,我们可以在配置中传递与AOF相关的详细信息,并根据flush_time的设置将周期性刷新到磁盘或每个操作记录到磁盘,flush_time以毫秒为单位,或设置为None

use sine_cache::{cache::AsyncCache, config::{AsyncCacheConfig, EvictionAsyncConfig, EvictionAOFConfig}};

#[tokio::main]
async fn main() {
  
    let capacity = 10; // Maximum number of entries in the cache.
    let mut cache = AsyncCache::new(AsyncCacheConfig::LFU(EvictionAsyncConfig {
        max_size: capacity,
        aof_config: Some(EvictionAOFConfig {
            folder: String::from("./data"), //folder in which persistent file should be written.
            cache_name: String::from("async_lof_cache"), //Unique cache name as with same name file will be created.
            flush_time: Some(5000) //After every 5000 milliseconds data will be flushed to disk.
        })
    })).await;

    // Inserting key-value pairs into the cache
    cache.put(1, String::from("One")).await;
    cache.put(1, String::from("one")).await; // Overwrites previous value
    cache.put(2, String::from("Two")).await;

    // Retrieving a value from the cache
    let value = cache.get(&1).await;
    assert!(value.is_some_and(|x| x == "one"));
}

自定义淘汰策略

也可以定义并使用与AsyncCacheCache的所有功能相关的自定义淘汰策略。

use sine_cache::eviction_policies::common::EvictionPolicy;
use sine_cache::{cache::AsyncCache, config::{AsyncCacheConfig, CustomEvictionAsyncConfig, CustomEvictionAOFConfig}};

pub struct CustomEviction<K> {
    _phantom: std::marker::PhantomData<K>,
}

impl<K: Eq + std::hash::Hash + Clone> CustomEviction<K> {
    pub fn new() -> Self{
        Self{
            _phantom: std::marker::PhantomData
        }
    }
}

impl<K: Eq + std::hash::Hash + Clone> EvictionPolicy<K> for CustomEviction<K> {
    fn on_get(&mut self, key: &K) {
        // nothing to do.
    }

    fn on_set(&mut self, key: K) {
        // nothing to do.
    }

    fn evict(&mut self) -> Option<K> {
        // nothing to do
        None
    }

    fn remove(&mut self, key: K) {
        //nothing to do
    }
}

#[tokio::main]
async fn main() {
  
    let capacity = 10; // Maximum number of entries in the cache.
    let mut cache = AsyncCache::new(AsyncCacheConfig::Custom(CustomEvictionAsyncConfig {
        max_size: capacity,
        aof_config: Some(CustomEvictionAOFConfig {
            folder: String::from("./data"), //folder in which persistent file should be written.
            cache_name: String::from("async_lof_custom_cache"), //Unique cache name as with same name file will be created.
            flush_time: Some(5000), //After every 5000 milliseconds data will be flushed to disk.
            persist_read_ops: true //whether to store reads also, true generally.
        }),
        policy: Box::new(CustomEviction::new())
    })).await;

    // Inserting key-value pairs into the cache
    cache.put(1, String::from("One")).await;
    cache.put(1, String::from("one")).await; // Overwrites previous value
    cache.put(2, String::from("Two")).await;

    // Retrieving a value from the cache
    let value = cache.get(&1).await;
    assert!(value.is_some_and(|x| x == "one"));
}

计划中的功能

AOF 压缩

定期压缩AOF文件,以防止追加文件变得过大。

许可证

本项目采用MIT许可证 - 有关详细信息,请参阅LICENSE文件。

依赖关系

~3–10MB
~97K SLoC