mappy_core/storage/
mod.rs

1//! Storage layer for mappy
2//!
3//! Provides different storage backends for persistence and durability.
4
5use crate::MapletResult;
6use async_trait::async_trait;
7use serde::{Deserialize, Serialize};
8
9pub mod aof;
10pub mod disk;
11pub mod hybrid;
12pub mod memory;
13
14/// Storage statistics
15#[derive(Debug, Clone, Serialize, Deserialize, Default)]
16pub struct StorageStats {
17    /// Total number of keys stored
18    pub total_keys: u64,
19    /// Memory usage in bytes
20    pub memory_usage: u64,
21    /// Disk usage in bytes
22    pub disk_usage: u64,
23    /// Number of operations performed
24    pub operations_count: u64,
25    /// Average operation latency in microseconds
26    pub avg_latency_us: u64,
27}
28
29/// Storage trait for different backends
30#[async_trait]
31pub trait Storage: Send + Sync {
32    /// Get a value by key
33    async fn get(&self, key: &str) -> MapletResult<Option<Vec<u8>>>;
34
35    /// Set a key-value pair
36    async fn set(&self, key: String, value: Vec<u8>) -> MapletResult<()>;
37
38    /// Delete a key
39    async fn delete(&self, key: &str) -> MapletResult<bool>;
40
41    /// Check if a key exists
42    async fn exists(&self, key: &str) -> MapletResult<bool>;
43
44    /// Get all keys
45    async fn keys(&self) -> MapletResult<Vec<String>>;
46
47    /// Clear all data
48    async fn clear_database(&self) -> MapletResult<()>;
49
50    /// Flush any pending writes
51    async fn flush(&self) -> MapletResult<()>;
52
53    /// Close the storage backend
54    async fn close(&self) -> MapletResult<()>;
55
56    /// Get storage statistics
57    async fn stats(&self) -> MapletResult<StorageStats>;
58}
59
60/// Storage factory for creating different backends
61pub struct StorageFactory;
62
63impl StorageFactory {
64    /// Create a storage backend based on persistence mode
65    pub async fn create_storage(
66        mode: PersistenceMode,
67        config: StorageConfig,
68    ) -> MapletResult<Box<dyn Storage>> {
69        match mode {
70            PersistenceMode::Memory => Ok(Box::new(memory::MemoryStorage::new(config)?)),
71            PersistenceMode::Disk => Ok(Box::new(disk::DiskStorage::new(config)?)),
72            PersistenceMode::AOF => Ok(Box::new(aof::AOFStorage::new(config)?)),
73            PersistenceMode::Hybrid => Ok(Box::new(hybrid::HybridStorage::new(config)?)),
74        }
75    }
76}
77
78/// Persistence mode for storage
79#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
80pub enum PersistenceMode {
81    /// In-memory only (no persistence)
82    Memory,
83    /// Append-only file
84    AOF,
85    /// Full durability (synchronous writes)
86    Disk,
87    /// Hybrid (memory + AOF)
88    Hybrid,
89}
90
91/// Storage configuration
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct StorageConfig {
94    /// Data directory for persistent storage
95    pub data_dir: String,
96    /// Maximum memory usage in bytes
97    pub max_memory: Option<u64>,
98    /// Enable compression
99    pub enable_compression: bool,
100    /// Sync interval for AOF mode (seconds)
101    pub sync_interval: u64,
102    /// Buffer size for writes
103    pub write_buffer_size: usize,
104}
105
106impl Default for StorageConfig {
107    fn default() -> Self {
108        Self {
109            data_dir: "./data".to_string(),
110            max_memory: None,
111            enable_compression: true,
112            sync_interval: 1,
113            write_buffer_size: 1024 * 1024, // 1MB
114        }
115    }
116}