do_memory_storage_redb/
patterns.rs1use crate::{Error, PATTERNS_TABLE, RedbStorage};
4use do_memory_core::{Pattern, Result, episode::PatternId};
5use redb::{ReadableDatabase, ReadableTable};
6use std::sync::Arc;
7use tracing::debug;
8use tracing::info;
9
10use crate::episodes::RedbQuery;
11
12impl RedbStorage {
13 pub async fn store_pattern(&self, pattern: &Pattern) -> Result<()> {
15 debug!("Storing pattern in cache: {}", pattern.id());
16 let db = Arc::clone(&self.db);
17 let pattern_id = pattern.id().to_string();
18 let pattern_bytes = postcard::to_allocvec(pattern)
19 .map_err(|e| Error::Storage(format!("Failed to serialize pattern: {}", e)))?;
20
21 tokio::task::spawn_blocking(move || {
22 let write_txn = db
23 .begin_write()
24 .map_err(|e| Error::Storage(format!("Failed to begin write transaction: {}", e)))?;
25
26 {
27 let mut table = write_txn
28 .open_table(PATTERNS_TABLE)
29 .map_err(|e| Error::Storage(format!("Failed to open patterns table: {}", e)))?;
30
31 table
32 .insert(pattern_id.as_str(), pattern_bytes.as_slice())
33 .map_err(|e| Error::Storage(format!("Failed to insert pattern: {}", e)))?;
34 }
35
36 write_txn
37 .commit()
38 .map_err(|e| Error::Storage(format!("Failed to commit transaction: {}", e)))?;
39
40 Ok::<(), Error>(())
41 })
42 .await
43 .map_err(|e| Error::Storage(format!("Task join error: {}", e)))??;
44
45 info!("Successfully cached pattern: {}", pattern.id());
46 Ok(())
47 }
48
49 pub async fn get_pattern(&self, pattern_id: PatternId) -> Result<Option<Pattern>> {
51 debug!("Retrieving pattern from cache: {}", pattern_id);
52 let db = Arc::clone(&self.db);
53 let pattern_id_str = pattern_id.to_string();
54
55 tokio::task::spawn_blocking(move || {
56 let read_txn = db
57 .begin_read()
58 .map_err(|e| Error::Storage(format!("Failed to begin read transaction: {}", e)))?;
59
60 let table = read_txn
61 .open_table(PATTERNS_TABLE)
62 .map_err(|e| Error::Storage(format!("Failed to open patterns table: {}", e)))?;
63
64 match table
65 .get(pattern_id_str.as_str())
66 .map_err(|e| Error::Storage(format!("Failed to get pattern: {}", e)))?
67 {
68 Some(bytes_guard) => {
69 let _bytes = bytes_guard.value();
70 let pattern: Pattern =
71 postcard::from_bytes(bytes_guard.value()).map_err(|e| {
72 Error::Storage(format!("Failed to deserialize pattern: {}", e))
73 })?;
74 Ok(Some(pattern))
75 }
76 None => Ok(None),
77 }
78 })
79 .await
80 .map_err(|e| Error::Storage(format!("Task join error: {}", e)))?
81 }
82
83 pub async fn get_all_patterns(&self, query: &RedbQuery) -> Result<Vec<Pattern>> {
85 debug!("Retrieving all patterns from cache");
86 let db = Arc::clone(&self.db);
87 let limit = query.limit;
88
89 tokio::task::spawn_blocking(move || {
90 let read_txn = db
91 .begin_read()
92 .map_err(|e| Error::Storage(format!("Failed to begin read transaction: {}", e)))?;
93
94 let table = read_txn
95 .open_table(PATTERNS_TABLE)
96 .map_err(|e| Error::Storage(format!("Failed to open patterns table: {}", e)))?;
97
98 let mut patterns = Vec::new();
99 let iter = table
100 .iter()
101 .map_err(|e| Error::Storage(format!("Failed to iterate patterns: {}", e)))?;
102
103 for (count, result) in iter.enumerate() {
104 if let Some(max) = limit {
105 if count >= max {
106 break;
107 }
108 }
109
110 let (_, bytes_guard) = result
111 .map_err(|e| Error::Storage(format!("Failed to read pattern entry: {}", e)))?;
112
113 let pattern: Pattern = postcard::from_bytes(bytes_guard.value())
114 .map_err(|e| Error::Storage(format!("Failed to deserialize pattern: {}", e)))?;
115
116 patterns.push(pattern);
117 }
118
119 Ok(patterns)
120 })
121 .await
122 .map_err(|e| Error::Storage(format!("Task join error: {}", e)))?
123 }
124}