Skip to main content

alopex_core/kv/
storage.rs

1use crate::error::Result;
2use crate::kv::any::AnyKV;
3use crate::kv::memory::MemoryKV;
4use crate::lsm::{LsmKV, LsmKVConfig};
5use std::path::PathBuf;
6
7#[cfg(feature = "s3")]
8use crate::kv::s3::S3Config;
9
10/// Storage mode selection for the KV store.
11pub enum StorageMode {
12    /// Disk-backed storage using LSM-Tree (file-mode).
13    Disk {
14        /// データディレクトリ(内部で WAL/SSTable を作成)。
15        path: PathBuf,
16        /// LSM-Tree 設定(None = デフォルト)。
17        config: Option<LsmKVConfig>,
18    },
19    /// Pure in-memory storage with optional memory cap.
20    Memory {
21        /// Optional memory cap in bytes; None means unlimited.
22        max_size: Option<usize>,
23    },
24    /// S3-backed storage (requires `s3` feature).
25    #[cfg(feature = "s3")]
26    S3 {
27        /// S3 configuration.
28        config: S3Config,
29    },
30}
31
32/// Factory for creating storage instances based on mode.
33pub struct StorageFactory;
34
35impl StorageFactory {
36    /// Create a KV store according to the requested mode.
37    ///
38    /// - Disk: LsmKV(file-mode)を使用する。
39    /// - Memory: 既存の MemoryKV を使用する。
40    /// - S3: S3KV(requires `s3` feature)を使用する。
41    pub fn create(mode: StorageMode) -> Result<AnyKV> {
42        match mode {
43            StorageMode::Disk { path, config } => {
44                let kv = match config {
45                    Some(cfg) => {
46                        let (store, _recovery) = LsmKV::open_with_config(&path, cfg)?;
47                        store
48                    }
49                    None => LsmKV::open(&path)?,
50                };
51                Ok(AnyKV::Lsm(Box::new(kv)))
52            }
53            StorageMode::Memory { max_size } => {
54                Ok(AnyKV::Memory(MemoryKV::new_with_limit(max_size)))
55            }
56            #[cfg(feature = "s3")]
57            StorageMode::S3 { config } => {
58                let kv = crate::kv::s3::S3KV::open(config)?;
59                Ok(AnyKV::S3(Box::new(kv)))
60            }
61        }
62    }
63}
64
65#[cfg(all(test, not(target_arch = "wasm32")))]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn create_memory_mode_returns_memorykv() {
71        let store = StorageFactory::create(StorageMode::Memory { max_size: None }).unwrap();
72        assert!(matches!(store, AnyKV::Memory(_)));
73    }
74
75    #[test]
76    fn create_disk_mode_returns_lsmkv() {
77        let dir = tempfile::tempdir().unwrap();
78        let store = StorageFactory::create(StorageMode::Disk {
79            path: dir.path().to_path_buf(),
80            config: None,
81        })
82        .unwrap();
83        assert!(matches!(store, AnyKV::Lsm(_)));
84    }
85}