From 17129a61150f02f8df1735073b01763576624fe9 Mon Sep 17 00:00:00 2001 From: Pierre Zemb Date: Sun, 3 Jan 2021 15:07:23 +0100 Subject: [PATCH] fix(foundationdb): generate the right subspace with a nested path on directory --- foundationdb/src/directory/mod.rs | 30 +++++++++++++------ foundationdb/src/directory/node.rs | 8 ++++-- foundationdb/tests/directory.rs | 46 ++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/foundationdb/src/directory/mod.rs b/foundationdb/src/directory/mod.rs index 04b7eb3e..e9d9b39c 100644 --- a/foundationdb/src/directory/mod.rs +++ b/foundationdb/src/directory/mod.rs @@ -167,9 +167,9 @@ impl DirectoryLayer { /// parent directory of newPath does not exist. pub async fn move_to( &self, - trx: &Transaction, - old_path: Vec, - new_path: Vec, + _trx: &Transaction, + _old_path: Vec, + _new_path: Vec, ) -> Result { unimplemented!("move is not supported yet") } @@ -178,8 +178,8 @@ impl DirectoryLayer { /// exists, and false otherwise. pub async fn remove( &self, - trx: &Transaction, - path: Vec, + _trx: &Transaction, + _path: Vec, ) -> Result { unimplemented!("move is not supported yet") } @@ -250,13 +250,21 @@ impl DirectoryLayer { return Err(DirectoryError::DirNotExists); } - let mut subspace = self.content_subspace.clone(); + let mut parent_subspace = self.content_subspace.clone(); for mut node in nodes { - let allocator = self.allocator.allocate(trx).await?; - subspace = node.create_subspace(&trx, allocator, &subspace).await?; + match node.content_subspace { + None => { + // creating subspace + let allocator = self.allocator.allocate(trx).await?; + parent_subspace = node + .create_subspace(&trx, allocator, &parent_subspace) + .await?; + } + Some(subspace) => parent_subspace = subspace.clone(), + } } - Ok(subspace) + Ok(parent_subspace) } /// checks the version of the directory within FDB @@ -330,12 +338,16 @@ impl DirectoryLayer { let mut subspace = self.node_subspace.to_owned(); + let mut node_path = vec![]; + for path_name in paths { + node_path.push(path_name.to_owned()); let mut next_node_key = vec![DEFAULT_SUB_DIRS]; pack_into(&path_name, &mut next_node_key); subspace = subspace.subspace(&next_node_key); let mut node = Node { + paths: node_path.clone(), layer: None, node_subspace: subspace.to_owned(), content_subspace: None, diff --git a/foundationdb/src/directory/node.rs b/foundationdb/src/directory/node.rs index 3ff06b25..2d720c30 100644 --- a/foundationdb/src/directory/node.rs +++ b/foundationdb/src/directory/node.rs @@ -12,9 +12,12 @@ use crate::{FdbError, RangeOption, Transaction}; /// Node are used to represent the paths generated by a Directory. /// They are stored in the `Directory.` +#[derive(Debug)] pub(crate) struct Node { pub(crate) layer: Option>, + pub(crate) paths: Vec, + pub(crate) node_subspace: Subspace, pub(crate) content_subspace: Option, } @@ -34,8 +37,9 @@ impl Node { } /// This will use the generated id and: - /// * persist the node in the directory subspace dedicated to nodes - /// * create the content_subspace and returns it + /// + /// * persist the node in the directory subspace dedicated to nodes + /// * create the content_subspace and returns it pub(crate) async fn create_subspace( &mut self, trx: &Transaction, diff --git a/foundationdb/tests/directory.rs b/foundationdb/tests/directory.rs index d6da77d2..bc7818dd 100644 --- a/foundationdb/tests/directory.rs +++ b/foundationdb/tests/directory.rs @@ -41,6 +41,13 @@ fn test_directory() { futures::executor::block_on(test_list(&db, &directory, vec![String::from("a")], 10)) .expect("failed to run"); + futures::executor::block_on(test_children_content_subspace( + &db, + &directory, + vec![String::from("c")], + )) + .expect("failed to run"); + futures::executor::block_on(test_bad_layer(&db)).expect("failed to run"); } @@ -76,6 +83,7 @@ async fn test_create_or_open_async( Ok(()) } +/// testing that we throwing Err(DirectoryError::IncompatibleLayer) async fn test_bad_layer(db: &Database) -> Result<(), DirectoryError> { let directory = DirectoryLayer { layer: vec![0u8], @@ -103,6 +111,7 @@ async fn test_bad_layer(db: &Database) -> Result<(), DirectoryError> { Ok(()) } +/// testing list functionality. Will open paths and create n sub-folders. async fn test_list( db: &Database, directory: &DirectoryLayer, @@ -145,3 +154,40 @@ async fn test_list( Ok(()) } + +/// checks that the content_subspace of the children is inside the parent +async fn test_children_content_subspace( + db: &Database, + directory: &DirectoryLayer, + paths: Vec, +) -> Result<(), DirectoryError> { + let trx = db.create_trx()?; + + eprintln!("parent = {:?}", paths.to_owned()); + + let root_subspace = directory.create_or_open(&trx, paths.to_owned()).await?; + + let mut children_path = paths.clone(); + children_path.push(String::from("nested")); + eprintln!("children = {:?}", children_path.to_owned()); + + let children_subspace = directory + .create_or_open(&trx, children_path.to_owned()) + .await?; + + assert!( + children_subspace.bytes().starts_with(root_subspace.bytes()), + "children subspace '{:?} does not start with parent subspace '{:?}'", + children_subspace.bytes(), + root_subspace.bytes() + ); + + trx.commit().await.expect("could not commit"); + let trx = db.create_trx()?; + + let open_children_subspace = directory.open(&trx, children_path.to_owned()).await?; + + assert_eq!(children_subspace.bytes(), open_children_subspace.bytes()); + + Ok(()) +}