Skip to content

Commit 43b122b

Browse files
committed
Implement MigratableKVStore for InMemoryStore
This was unimplemented for the in-memory kv store. Useful in tests so we can migrate data across all supported store implementations. AI-assisted-by: OpenAI Codex
1 parent 18fa93a commit 43b122b

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

src/io/in_memory_store.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use std::sync::atomic::{AtomicU64, Ordering};
1111
use std::sync::Mutex;
1212

1313
use lightning::io;
14-
use lightning::util::persist::{KVStore, PageToken, PaginatedKVStore, PaginatedListResponse};
14+
use lightning::util::persist::{
15+
KVStore, MigratableKVStore, PageToken, PaginatedKVStore, PaginatedListResponse,
16+
};
1517

1618
const IN_MEMORY_PAGE_SIZE: usize = 50;
1719

@@ -96,6 +98,28 @@ impl InMemoryStore {
9698
hash_map::Entry::Vacant(_) => Ok(Vec::new()),
9799
}
98100
}
101+
102+
fn list_all_keys_internal(&self) -> io::Result<Vec<(String, String, String)>> {
103+
let persisted_lock = self.persisted_bytes.lock().unwrap();
104+
let capacity = persisted_lock.values().map(|entries| entries.len()).sum();
105+
let mut keys = Vec::with_capacity(capacity);
106+
107+
for (prefixed_namespace, namespace_entries) in persisted_lock.iter() {
108+
let (primary_namespace, secondary_namespace) =
109+
prefixed_namespace.split_once('/').ok_or_else(|| {
110+
io::Error::new(io::ErrorKind::InvalidData, "Invalid namespace format")
111+
})?;
112+
for key in namespace_entries.keys() {
113+
keys.push((
114+
primary_namespace.to_string(),
115+
secondary_namespace.to_string(),
116+
key.clone(),
117+
));
118+
}
119+
}
120+
121+
Ok(keys)
122+
}
99123
}
100124

101125
impl KVStore for InMemoryStore {
@@ -187,5 +211,40 @@ impl PaginatedKVStore for InMemoryStore {
187211
}
188212
}
189213

214+
impl MigratableKVStore for InMemoryStore {
215+
fn list_all_keys(
216+
&self,
217+
) -> impl Future<Output = Result<Vec<(String, String, String)>, io::Error>> + 'static + Send {
218+
let res = self.list_all_keys_internal();
219+
async move { res }
220+
}
221+
}
222+
190223
unsafe impl Sync for InMemoryStore {}
191224
unsafe impl Send for InMemoryStore {}
225+
226+
#[cfg(test)]
227+
mod tests {
228+
use super::*;
229+
230+
#[tokio::test]
231+
async fn in_memory_store_list_all_keys() {
232+
let store = InMemoryStore::new();
233+
234+
KVStore::write(&store, "ns_a", "sub_a", "key_a", vec![1u8]).await.unwrap();
235+
KVStore::write(&store, "ns_a", "sub_b", "key_b", vec![2u8]).await.unwrap();
236+
KVStore::write(&store, "ns_b", "", "key_c", vec![3u8]).await.unwrap();
237+
238+
let mut keys = MigratableKVStore::list_all_keys(&store).await.unwrap();
239+
keys.sort();
240+
241+
assert_eq!(
242+
keys,
243+
vec![
244+
("ns_a".to_string(), "sub_a".to_string(), "key_a".to_string()),
245+
("ns_a".to_string(), "sub_b".to_string(), "key_b".to_string()),
246+
("ns_b".to_string(), "".to_string(), "key_c".to_string()),
247+
]
248+
);
249+
}
250+
}

0 commit comments

Comments
 (0)