Skip to main content

llm_optimizer_processor/storage/
traits.rs

1//! Storage traits
2
3use async_trait::async_trait;
4use chrono::{DateTime, Utc};
5use serde::{de::DeserializeOwned, Serialize};
6use std::fmt::Debug;
7
8use super::error::{StorageError, StorageResult};
9use super::types::{
10    Batch, EntryMetadata, Operation, Query, StorageBackend, StorageEntry, StorageHealth,
11    StorageMetadata, StorageStats, Transaction,
12};
13
14/// Core storage trait defining unified interface for all backends
15#[async_trait]
16pub trait Storage: Send + Sync + Debug {
17    /// Get backend type
18    fn backend(&self) -> StorageBackend;
19
20    /// Get storage metadata
21    async fn metadata(&self) -> StorageResult<StorageMetadata>;
22
23    /// Health check
24    async fn health_check(&self) -> StorageResult<StorageHealth>;
25
26    /// Get statistics
27    async fn stats(&self) -> StorageResult<StorageStats>;
28
29    // Basic CRUD operations
30
31    /// Insert a new entry
32    async fn insert<T: Serialize + DeserializeOwned + Send + Sync>(
33        &self,
34        table: &str,
35        key: &str,
36        value: &T,
37    ) -> StorageResult<()>
38    where
39        Self: Sized;
40
41    /// Insert entry with TTL (time-to-live in seconds)
42    async fn insert_with_ttl<T: Serialize + Send + Sync>(
43        &self,
44        table: &str,
45        key: &str,
46        value: &T,
47        ttl_seconds: i64,
48    ) -> StorageResult<()>
49    where
50        Self: Sized;
51
52    /// Get an entry by key
53    async fn get<T: DeserializeOwned + Serialize + Send + Sync>(
54        &self,
55        table: &str,
56        key: &str,
57    ) -> StorageResult<Option<StorageEntry<T>>>
58    where
59        Self: Sized;
60
61    /// Update an existing entry
62    async fn update<T: Serialize + Send + Sync>(
63        &self,
64        table: &str,
65        key: &str,
66        value: &T,
67    ) -> StorageResult<()>
68    where
69        Self: Sized;
70
71    /// Update entry with optimistic locking (version check)
72    async fn update_versioned<T: Serialize + Send + Sync>(
73        &self,
74        table: &str,
75        key: &str,
76        value: &T,
77        expected_version: u64,
78    ) -> StorageResult<()>
79    where
80        Self: Sized;
81
82    /// Delete an entry
83    async fn delete(&self, table: &str, key: &str) -> StorageResult<()>;
84
85    /// Check if entry exists
86    async fn exists(&self, table: &str, key: &str) -> StorageResult<bool>;
87
88    // Batch operations
89
90    /// Execute batch operations
91    async fn execute_batch(&self, batch: Batch) -> StorageResult<()>;
92
93    // Query operations
94
95    /// Query entries matching criteria
96    async fn query<T: DeserializeOwned + Serialize + Send + Sync + 'static>(
97        &self,
98        query: Query,
99    ) -> StorageResult<Vec<StorageEntry<T>>>
100    where
101        Self: Sized;
102
103    /// Count entries matching criteria
104    async fn count(&self, query: Query) -> StorageResult<usize>;
105
106    // Transaction support (not all backends support this)
107
108    /// Begin a transaction
109    async fn begin_transaction(&self) -> StorageResult<Transaction>;
110
111    /// Commit a transaction
112    async fn commit_transaction(&self, transaction: Transaction) -> StorageResult<()>;
113
114    /// Rollback a transaction
115    async fn rollback_transaction(&self, transaction: Transaction) -> StorageResult<()>;
116
117    // Advanced operations
118
119    /// Scan keys with prefix
120    async fn scan_prefix(&self, table: &str, prefix: &str) -> StorageResult<Vec<String>>;
121
122    /// Get multiple entries by keys
123    async fn get_multi<T: DeserializeOwned + Serialize + Send + Sync>(
124        &self,
125        table: &str,
126        keys: Vec<String>,
127    ) -> StorageResult<Vec<Option<StorageEntry<T>>>>
128    where
129        Self: Sized;
130
131    /// Delete multiple entries
132    async fn delete_multi(&self, table: &str, keys: Vec<String>) -> StorageResult<()>;
133
134    /// Atomic compare-and-swap
135    async fn compare_and_swap<T: Serialize + Send + Sync>(
136        &self,
137        table: &str,
138        key: &str,
139        expected_version: u64,
140        new_value: &T,
141    ) -> StorageResult<bool>
142    where
143        Self: Sized;
144
145    // Time-based operations
146
147    /// Get entries modified after timestamp
148    async fn get_modified_since<T: DeserializeOwned + Serialize + Send + Sync + 'static>(
149        &self,
150        table: &str,
151        since: DateTime<Utc>,
152    ) -> StorageResult<Vec<StorageEntry<T>>>
153    where
154        Self: Sized;
155
156    /// Get entries that expire before timestamp
157    async fn get_expiring_before<T: DeserializeOwned + Serialize + Send + Sync + 'static>(
158        &self,
159        table: &str,
160        before: DateTime<Utc>,
161    ) -> StorageResult<Vec<StorageEntry<T>>>
162    where
163        Self: Sized;
164
165    // Maintenance operations
166
167    /// Cleanup expired entries
168    async fn cleanup_expired(&self, table: &str) -> StorageResult<usize>;
169
170    /// Compact storage (if supported)
171    async fn compact(&self) -> StorageResult<()>;
172
173    /// Flush pending writes
174    async fn flush(&self) -> StorageResult<()>;
175
176    // Lifecycle
177
178    /// Initialize storage
179    async fn initialize(&mut self) -> StorageResult<()>;
180
181    /// Shutdown storage
182    async fn shutdown(&mut self) -> StorageResult<()>;
183}
184
185/// Cache-specific operations (for Redis)
186#[async_trait]
187pub trait CacheStorage: Storage {
188    /// Get TTL for a key (seconds remaining)
189    async fn ttl(&self, table: &str, key: &str) -> StorageResult<Option<i64>>;
190
191    /// Set expiration time for a key
192    async fn expire(&self, table: &str, key: &str, ttl_seconds: i64) -> StorageResult<()>;
193
194    /// Remove expiration from a key
195    async fn persist(&self, table: &str, key: &str) -> StorageResult<()>;
196
197    /// Increment a numeric value atomically
198    async fn increment(&self, table: &str, key: &str, delta: i64) -> StorageResult<i64>;
199
200    /// Decrement a numeric value atomically
201    async fn decrement(&self, table: &str, key: &str, delta: i64) -> StorageResult<i64>;
202
203    /// Get cache statistics
204    async fn cache_stats(&self) -> StorageResult<CacheStats>;
205}
206
207/// Cache statistics
208#[derive(Debug, Clone)]
209pub struct CacheStats {
210    pub hits: u64,
211    pub misses: u64,
212    pub evictions: u64,
213    pub memory_used_bytes: u64,
214    pub memory_available_bytes: u64,
215    pub keys_count: usize,
216}
217
218impl CacheStats {
219    pub fn hit_rate(&self) -> f64 {
220        let total = self.hits + self.misses;
221        if total == 0 {
222            0.0
223        } else {
224            self.hits as f64 / total as f64
225        }
226    }
227}
228
229/// Relational database operations (for PostgreSQL)
230#[async_trait]
231pub trait RelationalStorage: Storage {
232    /// Execute raw SQL query
233    async fn execute_sql(&self, sql: &str, params: Vec<SqlParam>) -> StorageResult<SqlResult>;
234
235    /// Execute SQL query and return results
236    async fn query_sql<T: DeserializeOwned + Send + Sync>(
237        &self,
238        sql: &str,
239        params: Vec<SqlParam>,
240    ) -> StorageResult<Vec<T>>
241    where
242        Self: Sized;
243
244    /// Create index
245    async fn create_index(
246        &self,
247        table: &str,
248        index_name: &str,
249        columns: Vec<String>,
250        unique: bool,
251    ) -> StorageResult<()>;
252
253    /// Drop index
254    async fn drop_index(&self, index_name: &str) -> StorageResult<()>;
255
256    /// Vacuum table (optimize storage)
257    async fn vacuum(&self, table: &str) -> StorageResult<()>;
258
259    /// Analyze table (update statistics)
260    async fn analyze(&self, table: &str) -> StorageResult<()>;
261}
262
263/// SQL parameter
264#[derive(Debug, Clone)]
265pub enum SqlParam {
266    String(String),
267    Integer(i64),
268    Float(f64),
269    Boolean(bool),
270    DateTime(DateTime<Utc>),
271    Null,
272}
273
274/// SQL query result
275#[derive(Debug, Clone)]
276pub struct SqlResult {
277    pub rows_affected: u64,
278}
279
280/// Key-value storage operations (for Sled)
281#[async_trait]
282pub trait KeyValueStorage: Storage {
283    /// Get value by key as bytes
284    async fn get_bytes(&self, table: &str, key: &str) -> StorageResult<Option<Vec<u8>>>;
285
286    /// Set value as bytes
287    async fn set_bytes(&self, table: &str, key: &str, value: Vec<u8>) -> StorageResult<()>;
288
289    /// Iterate over all keys with prefix
290    async fn iter_prefix(&self, table: &str, prefix: &str) -> StorageResult<Vec<(String, Vec<u8>)>>;
291
292    /// Get range of keys
293    async fn get_range(
294        &self,
295        table: &str,
296        start: &str,
297        end: &str,
298    ) -> StorageResult<Vec<(String, Vec<u8>)>>;
299
300    /// Merge value (append for log-structured merge trees)
301    async fn merge(&self, table: &str, key: &str, value: Vec<u8>) -> StorageResult<()>;
302}
303
304/// Pub/Sub operations (for Redis)
305#[async_trait]
306pub trait PubSubStorage: Storage {
307    /// Publish message to channel
308    async fn publish(&self, channel: &str, message: &[u8]) -> StorageResult<usize>;
309
310    /// Subscribe to channel
311    async fn subscribe(&self, channel: &str) -> StorageResult<Box<dyn Subscriber>>;
312
313    /// Unsubscribe from channel
314    async fn unsubscribe(&self, channel: &str) -> StorageResult<()>;
315}
316
317/// Subscriber trait for receiving messages
318#[async_trait]
319pub trait Subscriber: Send + Sync {
320    /// Receive next message
321    async fn next_message(&mut self) -> StorageResult<Option<Vec<u8>>>;
322}
323
324/// Migration operations
325#[async_trait]
326pub trait Migrator: Send + Sync {
327    /// Apply pending migrations
328    async fn migrate(&self) -> StorageResult<usize>;
329
330    /// Rollback last migration
331    async fn rollback(&self) -> StorageResult<()>;
332
333    /// Get applied migrations
334    async fn applied_migrations(&self) -> StorageResult<Vec<Migration>>;
335
336    /// Get pending migrations
337    async fn pending_migrations(&self) -> StorageResult<Vec<Migration>>;
338}
339
340/// Migration metadata
341#[derive(Debug, Clone)]
342pub struct Migration {
343    pub id: String,
344    pub name: String,
345    pub applied_at: Option<DateTime<Utc>>,
346    pub checksum: String,
347}
348
349/// Backup operations
350#[async_trait]
351pub trait Backup: Send + Sync {
352    /// Create backup
353    async fn create_backup(&self, path: &str) -> StorageResult<BackupMetadata>;
354
355    /// Restore from backup
356    async fn restore_backup(&self, path: &str) -> StorageResult<()>;
357
358    /// List available backups
359    async fn list_backups(&self, directory: &str) -> StorageResult<Vec<BackupMetadata>>;
360
361    /// Delete backup
362    async fn delete_backup(&self, path: &str) -> StorageResult<()>;
363}
364
365/// Backup metadata
366#[derive(Debug, Clone)]
367pub struct BackupMetadata {
368    pub path: String,
369    pub created_at: DateTime<Utc>,
370    pub size_bytes: u64,
371    pub checksum: String,
372}