Skip to content

Commit 98239df

Browse files
committed
Implement KVStoreMigrator for FilesystemStore
We implement the new interface on `FilesystemStore`, in particular `list_all_keys`.
1 parent 219f535 commit 98239df

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, KVStoreMigrator};
55
use lightning::util::string::PrintableString;
66

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

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

0 commit comments

Comments
 (0)