rexis_rag/storage/
memory.rs

1//! # Memory Trait - Abstract memory interface for RRAG storage
2//!
3//! This module provides the core Memory trait that abstracts over different storage backends.
4//! All storage implementations (in-memory, database, etc.) implement this trait.
5
6use crate::RragResult;
7use async_trait::async_trait;
8use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11/// Represents a value that can be stored in memory
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub enum MemoryValue {
14    /// String value
15    String(String),
16
17    /// Integer value
18    Integer(i64),
19
20    /// Float value
21    Float(f64),
22
23    /// Boolean value
24    Boolean(bool),
25
26    /// JSON value
27    Json(serde_json::Value),
28
29    /// Binary data
30    Bytes(Vec<u8>),
31
32    /// List of values
33    List(Vec<MemoryValue>),
34
35    /// Map of values
36    Map(HashMap<String, MemoryValue>),
37}
38
39impl MemoryValue {
40    /// Convert to string if possible
41    pub fn as_string(&self) -> Option<&str> {
42        match self {
43            MemoryValue::String(s) => Some(s),
44            _ => None,
45        }
46    }
47
48    /// Convert to integer if possible
49    pub fn as_integer(&self) -> Option<i64> {
50        match self {
51            MemoryValue::Integer(i) => Some(*i),
52            _ => None,
53        }
54    }
55
56    /// Convert to float if possible
57    pub fn as_float(&self) -> Option<f64> {
58        match self {
59            MemoryValue::Float(f) => Some(*f),
60            _ => None,
61        }
62    }
63
64    /// Convert to boolean if possible
65    pub fn as_boolean(&self) -> Option<bool> {
66        match self {
67            MemoryValue::Boolean(b) => Some(*b),
68            _ => None,
69        }
70    }
71
72    /// Convert to JSON if possible
73    pub fn as_json(&self) -> Option<&serde_json::Value> {
74        match self {
75            MemoryValue::Json(j) => Some(j),
76            _ => None,
77        }
78    }
79
80    /// Convert to bytes if possible
81    pub fn as_bytes(&self) -> Option<&[u8]> {
82        match self {
83            MemoryValue::Bytes(b) => Some(b),
84            _ => None,
85        }
86    }
87}
88
89impl From<String> for MemoryValue {
90    fn from(s: String) -> Self {
91        MemoryValue::String(s)
92    }
93}
94
95impl From<&str> for MemoryValue {
96    fn from(s: &str) -> Self {
97        MemoryValue::String(s.to_string())
98    }
99}
100
101impl From<i64> for MemoryValue {
102    fn from(i: i64) -> Self {
103        MemoryValue::Integer(i)
104    }
105}
106
107impl From<f64> for MemoryValue {
108    fn from(f: f64) -> Self {
109        MemoryValue::Float(f)
110    }
111}
112
113impl From<bool> for MemoryValue {
114    fn from(b: bool) -> Self {
115        MemoryValue::Boolean(b)
116    }
117}
118
119impl From<serde_json::Value> for MemoryValue {
120    fn from(j: serde_json::Value) -> Self {
121        MemoryValue::Json(j)
122    }
123}
124
125impl From<Vec<u8>> for MemoryValue {
126    fn from(b: Vec<u8>) -> Self {
127        MemoryValue::Bytes(b)
128    }
129}
130
131/// Query options for memory operations
132#[derive(Debug, Clone, Default)]
133pub struct MemoryQuery {
134    /// Key pattern/prefix to match
135    pub key_pattern: Option<String>,
136
137    /// Namespace/collection filter
138    pub namespace: Option<String>,
139
140    /// Maximum results
141    pub limit: Option<usize>,
142
143    /// Skip first N results
144    pub offset: Option<usize>,
145
146    /// Sort order
147    pub sort_order: Option<SortOrder>,
148}
149
150#[derive(Debug, Clone)]
151pub enum SortOrder {
152    /// Sort by key ascending
153    KeyAsc,
154    /// Sort by key descending
155    KeyDesc,
156    /// Sort by creation time ascending
157    CreatedAsc,
158    /// Sort by creation time descending
159    CreatedDesc,
160}
161
162impl MemoryQuery {
163    pub fn new() -> Self {
164        Self::default()
165    }
166
167    pub fn with_pattern(mut self, pattern: impl Into<String>) -> Self {
168        self.key_pattern = Some(pattern.into());
169        self
170    }
171
172    pub fn with_namespace(mut self, namespace: impl Into<String>) -> Self {
173        self.namespace = Some(namespace.into());
174        self
175    }
176
177    pub fn with_limit(mut self, limit: usize) -> Self {
178        self.limit = Some(limit);
179        self
180    }
181
182    pub fn with_offset(mut self, offset: usize) -> Self {
183        self.offset = Some(offset);
184        self
185    }
186}
187
188/// Core Memory trait - abstract interface for all storage backends
189#[async_trait]
190pub trait Memory: Send + Sync {
191    /// Get the name of this memory backend
192    fn backend_name(&self) -> &str;
193
194    /// Set a value in memory
195    async fn set(&self, key: &str, value: MemoryValue) -> RragResult<()>;
196
197    /// Get a value from memory
198    async fn get(&self, key: &str) -> RragResult<Option<MemoryValue>>;
199
200    /// Delete a value from memory
201    async fn delete(&self, key: &str) -> RragResult<bool>;
202
203    /// Check if a key exists
204    async fn exists(&self, key: &str) -> RragResult<bool>;
205
206    /// List all keys matching a query
207    async fn keys(&self, query: &MemoryQuery) -> RragResult<Vec<String>>;
208
209    /// Get multiple values at once
210    async fn mget(&self, keys: &[String]) -> RragResult<Vec<Option<MemoryValue>>>;
211
212    /// Set multiple values at once
213    async fn mset(&self, pairs: &[(String, MemoryValue)]) -> RragResult<()>;
214
215    /// Delete multiple keys at once
216    async fn mdelete(&self, keys: &[String]) -> RragResult<usize>;
217
218    /// Clear all data (with optional namespace)
219    async fn clear(&self, namespace: Option<&str>) -> RragResult<()>;
220
221    /// Get count of keys
222    async fn count(&self, namespace: Option<&str>) -> RragResult<usize>;
223
224    /// Check if memory backend is healthy
225    async fn health_check(&self) -> RragResult<bool>;
226
227    /// Get memory statistics
228    async fn stats(&self) -> RragResult<MemoryStats>;
229}
230
231/// Memory backend statistics
232#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct MemoryStats {
234    /// Total number of keys
235    pub total_keys: usize,
236
237    /// Estimated memory usage in bytes
238    pub memory_bytes: u64,
239
240    /// Backend type
241    pub backend_type: String,
242
243    /// Number of namespaces
244    pub namespace_count: usize,
245
246    /// Last updated timestamp
247    pub last_updated: chrono::DateTime<chrono::Utc>,
248
249    /// Additional backend-specific stats
250    pub extra: HashMap<String, serde_json::Value>,
251}