Skip to content

Commit

Permalink
Implement MigratableKVStore for FilesystemStore
Browse files Browse the repository at this point in the history
We implement the new interface on `FilesystemStore`, in particular
`list_all_keys`.
  • Loading branch information
tnull committed Dec 12, 2024
1 parent 683a2b2 commit b75d953
Showing 1 changed file with 69 additions and 1 deletion.
70 changes: 69 additions & 1 deletion lightning-persister/src/fs_store.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Objects related to [`FilesystemStore`] live here.
use crate::utils::{check_namespace_key_validity, is_valid_kvstore_str};

use lightning::util::persist::KVStore;
use lightning::util::persist::{KVStore, MigratableKVStore};

use std::collections::HashMap;
use std::fs;
Expand Down Expand Up @@ -404,6 +404,74 @@ fn get_key_from_dir_entry(p: &Path, base_path: &Path) -> Result<String, lightnin
}
}

impl MigratableKVStore for FilesystemStore {
fn list_all_keys(&self) -> Result<Vec<(String, String, String)>, lightning::io::Error> {
let prefixed_dest = self.data_dir.clone();
if !prefixed_dest.exists() {
return Ok(Vec::new());
}

let mut keys = Vec::new();

'primary_loop: for primary_entry in fs::read_dir(&prefixed_dest)? {
let primary_entry = primary_entry?;
let primary_path = primary_entry.path();

if dir_entry_is_key(&primary_path)? {
let primary_namespace = "".to_string();
let secondary_namespace = "".to_string();
let key = get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
keys.push((primary_namespace, secondary_namespace, key));
continue 'primary_loop;
}

// The primary_entry is actually also a directory.
'secondary_loop: for secondary_entry in fs::read_dir(&primary_path)? {
let secondary_entry = secondary_entry?;
let secondary_path = secondary_entry.path();

if dir_entry_is_key(&secondary_path)? {
let primary_namespace = get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
let secondary_namespace = "".to_string();
let key = get_key_from_dir_entry(&secondary_path, &primary_path)?;
keys.push((primary_namespace, secondary_namespace, key));
continue 'secondary_loop;
}

// The secondary_entry is actually also a directory.
for tertiary_entry in fs::read_dir(&secondary_path)? {
let tertiary_entry = tertiary_entry?;
let tertiary_path = tertiary_entry.path();

if dir_entry_is_key(&tertiary_path)? {
let primary_namespace =
get_key_from_dir_entry(&primary_path, &prefixed_dest)?;
let secondary_namespace =
get_key_from_dir_entry(&secondary_path, &primary_path)?;
let key = get_key_from_dir_entry(&tertiary_path, &secondary_path)?;
keys.push((primary_namespace, secondary_namespace, key));
} else {
debug_assert!(
false,
"Failed to list keys of path {:?}: only two levels of namespaces are supported",
tertiary_path.to_str()
);
let msg = format!(
"Failed to list keys of path {:?}: only two levels of namespaces are supported",
tertiary_path.to_str()
);
return Err(lightning::io::Error::new(
lightning::io::ErrorKind::Other,
msg,
));
}
}
}
}
Ok(keys)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit b75d953

Please sign in to comment.