c82af60f81
- 新增 src/memory/store/sqlite_store.rs(SqliteStore + 9 个内联测试)
- 基于 rusqlite 0.32(bundled),使用 Arc<Mutex<Connection>> + spawn_blocking
- WAL 模式 + synchronous=NORMAL + busy_timeout=5s + PRAGMA user_version
schema 版本管理
- created_at 归一化为 UTC 的 RFC 3339 TEXT,字典序等价时间序
- 错误精细映射:SqliteFailure/InvalidQuery → InvalidInput;
FromSqlConversionFailure → Serialization;其他 → Storage
- 9 个测试覆盖 CRUD、upsert、prefix/since/offset+limit 过滤、
10 写者 × 10 次并发、持久化 round-trip、trait-box 互换兼容性
依赖:
- rusqlite = { version = "0.32", features = ["bundled"] }
- time 增补 features: parsing, formatting, macros
- dev-dependencies: tempfile = "3"
测试:199 → 200 pass(191 原有 + 9 新增)
63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
//! MemoryStore 抽象接口与默认实现。
|
||
|
||
use async_trait::async_trait;
|
||
|
||
use crate::memory::error::MemoryError;
|
||
use crate::memory::types::{MemoryFilter, MemoryItem};
|
||
|
||
pub mod in_memory;
|
||
pub mod sqlite_store;
|
||
|
||
pub use in_memory::InMemoryStore;
|
||
pub use sqlite_store::SqliteStore;
|
||
|
||
/// 底层记忆存储抽象接口。
|
||
///
|
||
/// 下游可实现此 trait 以对接持久化后端(JSON 文件、SQLite、Redis 等)。
|
||
/// 默认实现 [`InMemoryStore`] 基于进程内 HashMap。
|
||
#[async_trait]
|
||
pub trait MemoryStore: Send + Sync {
|
||
/// 保存/覆盖一个 MemoryItem(upsert 语义)。
|
||
/// - 如果 id 不存在,则插入新条目
|
||
/// - 如果 id 已存在,则覆盖旧条目
|
||
async fn save(&self, item: MemoryItem) -> Result<(), MemoryError>;
|
||
|
||
/// 根据 id 获取一个 MemoryItem。
|
||
async fn get(&self, id: &str) -> Result<Option<MemoryItem>, MemoryError>;
|
||
|
||
/// 根据 id 删除一个 MemoryItem。
|
||
async fn delete(&self, id: &str) -> Result<(), MemoryError>;
|
||
|
||
/// 根据 filter 列出 MemoryItem。
|
||
async fn list(&self, filter: &MemoryFilter) -> Result<Vec<MemoryItem>, MemoryError>;
|
||
}
|
||
|
||
/// 淘汰策略。
|
||
#[derive(Debug, Clone)]
|
||
#[non_exhaustive]
|
||
pub enum EvictionPolicy {
|
||
/// 不淘汰(默认)。
|
||
None,
|
||
/// 超过存活时间(秒)淘汰。
|
||
Ttl { ttl_secs: u64 },
|
||
/// 超过容量上限淘汰最旧(基于 created_at)。
|
||
Capacity { max_items: usize },
|
||
}
|
||
|
||
/// 淘汰配置。
|
||
#[derive(Debug, Clone)]
|
||
pub struct EvictionConfig {
|
||
pub policy: EvictionPolicy,
|
||
/// 每写入 N 条后检查一次淘汰条件。
|
||
pub check_interval: usize,
|
||
}
|
||
|
||
impl Default for EvictionConfig {
|
||
fn default() -> Self {
|
||
Self {
|
||
policy: EvictionPolicy::None,
|
||
check_interval: 64,
|
||
}
|
||
}
|
||
}
|