Skip to content

Commit b75d953

Browse files
committed
Implement MigratableKVStore for FilesystemStore
We implement the new interface on `FilesystemStore`, in particular `list_all_keys`.
1 parent 683a2b2 commit b75d953

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

lightning-persister/src/fs_store.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Objects related to [`FilesystemStore`] live here.
22
use crate::utils::{check_namespace_key_validity, is_valid_kvstore_str};
33

4-
use lightning::util::persist::KVStore;
4+
use lightning::util::persist::{KVStore, MigratableKVStore};
55

66
use std::collections::HashMap;
77
use std::fs;
@@ -404,6 +404,74 @@ fn get_key_from_dir_entry(p: &Path, base_path: &Path) -> Result<String, lightnin
404404
}
405405
}
406406

407+
impl MigratableKVStore for FilesystemStore {
408+
fn list_all_keys(&self) -> Result<Vec<(String, String, String)>, lightning::io::Error> {
409+
let prefixed_dest = self.data_dir.clone();
410+
if !prefixed_dest.exists() {
411+
return Ok(Vec::new());
412+
}
413+
414+
let mut keys = Vec::new();
415+
416+
'primary_loop: for primary_entry in fs::read_dir(&prefixed_dest)? {
417+
let primary_entry = primary_entry?;
418+
let primary_path = primary_entry.path();
419+
420+
if dir_entry_is_key(&primary_path)? {
421+
let primary_namespace = "".to_string();
422+
let secondary_namespace = "".to_string();
423+
let key = get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
424+
keys.push((primary_namespace, secondary_namespace, key));
425+
continue 'primary_loop;
426+
}
427+
428+
// The primary_entry is actually also a directory.
429+
'secondary_loop: for secondary_entry in fs::read_dir(&primary_path)? {
430+
let secondary_entry = secondary_entry?;
431+
let secondary_path = secondary_entry.path();
432+
433+
if dir_entry_is_key(&secondary_path)? {
434+
let primary_namespace = get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
435+
let secondary_namespace = "".to_string();
436+
let key = get_key_from_dir_entry(&secondary_path, &primary_path)?;
437+
keys.push((primary_namespace, secondary_namespace, key));
438+
continue 'secondary_loop;
439+
}
440+
441+
// The secondary_entry is actually also a directory.
442+
for tertiary_entry in fs::read_dir(&secondary_path)? {
443+
let tertiary_entry = tertiary_entry?;
444+
let tertiary_path = tertiary_entry.path();
445+
446+
if dir_entry_is_key(&tertiary_path)? {
447+
let primary_namespace =
448+
get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
449+
let secondary_namespace =
450+
get_key_from_dir_entry(&secondary_path, &primary_path)?;
451+
let key = get_key_from_dir_entry(&tertiary_path, &secondary_path)?;
452+
keys.push((primary_namespace, secondary_namespace, key));
453+
} else {
454+
debug_assert!(
455+
false,
456+
"Failed to list keys of path {:?}: only two levels of namespaces are supported",
457+
tertiary_path.to_str()
458+
);
459+
let msg = format!(
460+
"Failed to list keys of path {:?}: only two levels of namespaces are supported",
461+
tertiary_path.to_str()
462+
);
463+
return Err(lightning::io::Error::new(
464+
lightning::io::ErrorKind::Other,
465+
msg,
466+
));
467+
}
468+
}
469+
}
470+
}
471+
Ok(keys)
472+
}
473+
}
474+
407475
#[cfg(test)]
408476
mod tests {
409477
use super::*;

0 commit comments

Comments
 (0)