Skip to content

Commit 0291659

Browse files
Fix FsStore::list and path parsing
co-authored-by: Issac Kelly <[email protected]>
1 parent f95edd1 commit 0291659

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

src/fs_store.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::{
22
collections::{HashMap, HashSet},
33
io::Write,
44
path::{Path, PathBuf},
5+
str,
56
};
67

78
use crate::DocumentId;
@@ -20,10 +21,10 @@ use error::ErrorKind;
2021
/// ## Storage layout
2122
///
2223
/// In order to reduce the number of files in a single directory we follow git
23-
/// in splaying the files over 256 subdirectries using the first two bytes of
24+
/// in splaying the files over 256 subdirectories using the first two bytes of
2425
/// the SHA256 hash of the document ID. Then within each subdirectory we use
25-
/// the full SHA256 hash of the document ID as a directory within which we
26-
/// store the incremental and snapshots saves of a document. I.e.
26+
/// the hex encoding of the document ID as a directory within which we store the
27+
/// incremental and snapshots saves of a document. I.e.
2728
///
2829
/// ```sh
2930
/// <root>/
@@ -39,8 +40,9 @@ use error::ErrorKind;
3940
/// on other peers and for the splaying to be useful we need to guarantee a
4041
/// uniform distribution of documents across the subdirectories.
4142
///
42-
/// Likewise we use the hex encoding of the document ID as the filename to avoid
43-
/// any issues with non-UTF8 characters in the document ID.
43+
/// Likewise we use the hex encoding of the document ID as the 2nd-level
44+
/// directory name to avoid any issues with non-UTF8 characters in the document
45+
/// ID.
4446
///
4547
/// ## Compaction
4648
///
@@ -51,7 +53,7 @@ use error::ErrorKind;
5153
/// 2. Load the data into an automerge document
5254
/// 3. `automerge::Automerge::save` the document to a temporary file
5355
/// 4. Rename the temporary file to a file in the data directory named
54-
/// `SHA356(automerge::Automerge::get_heads)`.snapshot`
56+
/// `<sha256(heads)>.snapshot`
5557
/// 5. Delete all the files we loaded in step 1.
5658
///
5759
/// The fact that we name the file after the heads of the document means that
@@ -122,14 +124,14 @@ impl FsStore {
122124
let metadata = entry
123125
.metadata()
124126
.map_err(|e| Error(ErrorKind::ErrReadingLevel2Path(entry.path(), e)))?;
125-
if metadata.is_dir() {
127+
if !metadata.is_dir() {
126128
tracing::warn!(
127-
non_file_path=%entry.path().display(),
128-
"unexpected directory at level2 of database"
129+
non_dir_path=%entry.path().display(),
130+
"unexpected non-directory at level2 of database"
129131
);
130132
continue;
131133
}
132-
let Some(doc_paths) = DocIdPaths::parse(&level1, entry.path()) else {
134+
let Some(doc_paths) = DocIdPaths::parse(entry.path()) else {
133135
tracing::warn!(
134136
non_doc_path=%entry.path().display(),
135137
"unexpected non-document path at level2 of database"
@@ -236,15 +238,16 @@ impl<'a> From<&'a DocumentId> for DocIdPaths {
236238
}
237239

238240
impl DocIdPaths {
239-
fn parse<P1: AsRef<Path>, P2: AsRef<Path>>(level1: P1, level2: P2) -> Option<Self> {
240-
let level1 = level1.as_ref().to_str()?;
241+
fn parse<P: AsRef<Path>>(level2: P) -> Option<Self> {
242+
let level2 = level2.as_ref();
243+
let level1 = level2.parent()?.file_name()?.to_str()?;
241244
let prefix = hex::decode(level1).ok()?;
242245
let prefix = <[u8; 2]>::try_from(prefix).ok()?;
243246

244-
let level2 = level2.as_ref().to_str()?;
247+
let level2 = level2.file_name()?.to_str()?;
245248
let doc_id_bytes = hex::decode(level2).ok()?;
246-
let doc_id_str = String::from_utf8(doc_id_bytes).ok()?;
247-
let doc_id = DocumentId::from(doc_id_str.as_str());
249+
let doc_id_str = str::from_utf8(&doc_id_bytes).ok()?;
250+
let doc_id = DocumentId::from(doc_id_str);
248251
let result = Self::from(&doc_id);
249252
if result.prefix != prefix {
250253
None

tests/fs_storage/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ fn fs_store_crud() {
4040

4141
store.append(&doc_id, change2.bytes().as_ref()).unwrap();
4242

43+
// check that list is working
44+
let result = store.list().unwrap();
45+
let expected = &[doc_id.clone()];
46+
assert_eq!(&result, expected);
47+
4348
let result = store.get(&doc_id).unwrap().unwrap();
4449
assert_permutation_of!(result, vec![change1.bytes(), change2.bytes()]);
4550

0 commit comments

Comments
 (0)