mappy_core/storage/
mod.rs

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