Skip to content

Commit 5b44344

Browse files
committed
Implement MigratableKVStore for FilesystemStore
We implement the new interface on `FilesystemStore`, in particular `list_all_keys`.
1 parent 71612fd commit 5b44344

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;
@@ -419,6 +419,72 @@ fn get_key_from_dir_entry(p: &Path, base_path: &Path) -> Result<String, lightnin
419419
}
420420
}
421421

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

0 commit comments

Comments
 (0)