Skip to content

Commit 96f7bfd

Browse files
committed
Implement MigratableKVStore for FilesystemStore
We implement the new interface on `FilesystemStore`, in particular `list_all_keys`.
1 parent d69a5ee commit 96f7bfd

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

lightning-persister/src/fs_store.rs

Lines changed: 67 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
use lightning::util::string::PrintableString;
66

77
use std::collections::HashMap;
@@ -425,6 +425,72 @@ fn get_key_from_dir_entry(p: &Path, base_path: &Path) -> Result<String, lightnin
425425
}
426426
}
427427

428+
impl MigratableKVStore for FilesystemStore {
429+
fn list_all_keys(&self) -> Result<Vec<(String, String, String)>, lightning::io::Error> {
430+
let prefixed_dest = &self.data_dir;
431+
if !prefixed_dest.exists() {
432+
return Ok(Vec::new());
433+
}
434+
435+
let mut keys = Vec::new();
436+
437+
'primary_loop: for primary_entry in fs::read_dir(prefixed_dest)? {
438+
let primary_path = primary_entry?.path();
439+
440+
if dir_entry_is_key(&primary_path)? {
441+
let primary_namespace = String::new();
442+
let secondary_namespace = String::new();
443+
let key = get_key_from_dir_entry(&primary_path, prefixed_dest)?;
444+
keys.push((primary_namespace, secondary_namespace, key));
445+
continue 'primary_loop;
446+
}
447+
448+
// The primary_entry is actually also a directory.
449+
'secondary_loop: for secondary_entry in fs::read_dir(&primary_path)? {
450+
let secondary_path = secondary_entry?.path();
451+
452+
if dir_entry_is_key(&secondary_path)? {
453+
let primary_namespace = get_key_from_dir_entry(&primary_path, prefixed_dest)?;
454+
let secondary_namespace = String::new();
455+
let key = get_key_from_dir_entry(&secondary_path, &primary_path)?;
456+
keys.push((primary_namespace, secondary_namespace, key));
457+
continue 'secondary_loop;
458+
}
459+
460+
// The secondary_entry is actually also a directory.
461+
for tertiary_entry in fs::read_dir(&secondary_path)? {
462+
let tertiary_entry = tertiary_entry?;
463+
let tertiary_path = tertiary_entry.path();
464+
465+
if dir_entry_is_key(&tertiary_path)? {
466+
let primary_namespace =
467+
get_key_from_dir_entry(&primary_path, prefixed_dest)?;
468+
let secondary_namespace =
469+
get_key_from_dir_entry(&secondary_path, &primary_path)?;
470+
let key = get_key_from_dir_entry(&tertiary_path, &secondary_path)?;
471+
keys.push((primary_namespace, secondary_namespace, key));
472+
} else {
473+
debug_assert!(
474+
false,
475+
"Failed to list keys of path {}: only two levels of namespaces are supported",
476+
PrintableString(tertiary_path.to_str().unwrap_or_default())
477+
);
478+
let msg = format!(
479+
"Failed to list keys of path {}: only two levels of namespaces are supported",
480+
PrintableString(tertiary_path.to_str().unwrap_or_default())
481+
);
482+
return Err(lightning::io::Error::new(
483+
lightning::io::ErrorKind::Other,
484+
msg,
485+
));
486+
}
487+
}
488+
}
489+
}
490+
Ok(keys)
491+
}
492+
}
493+
428494
#[cfg(test)]
429495
mod tests {
430496
use super::*;

0 commit comments

Comments
 (0)