Skip to content

Commit

Permalink
fix(foundationdb): use right subspace during Directory.Remove
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreZ committed Jan 10, 2021
1 parent 6c301cd commit 920918a
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 15 deletions.
33 changes: 24 additions & 9 deletions foundationdb/src/directory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,9 @@ impl DirectoryLayer {
paths: Vec<String>,
) -> Result<bool, DirectoryError> {
let nodes = self.find_nodes(trx, paths.to_owned()).await?;

match nodes.last() {
None => Err(DirectoryError::DirNotExists),
Some(_) => Ok(true),
None => Ok(false),
Some(node) => Ok(node.content_subspace.is_some()),
}
}

Expand Down Expand Up @@ -220,20 +219,35 @@ impl DirectoryLayer {
.await?;

last_node_from_old_path
.delete_content_subspace(&trx)
.delete_content_from_node_subspace(&trx)
.await?;

Ok(true)
}

/// Exists returns true if the directory at path (relative to this Directory)
/// exists, and false otherwise.
/// `Remove` the subdirectory of this Directory located at `path` and all of its subdirectories,
/// as well as all of their contents.
pub async fn remove(
&self,
_trx: &Transaction,
_path: Vec<String>,
trx: &Transaction,
path: Vec<String>,
) -> Result<bool, DirectoryError> {
unimplemented!("move is not supported yet")
self.check_version(trx, false).await?;
if path.is_empty() {
return Err(DirectoryError::NoPathProvided);
}

let nodes = self.find_nodes(&trx, path.to_owned()).await?;

match nodes.last() {
None => Ok(false),
Some(node) => {
println!("found a node to delete: {:?}", node);
node.delete_content_from_node_subspace(&trx).await?;
node.delete_content_from_content_subspace(&trx).await?;
Ok(true)
}
}
}

/// List returns the names of the immediate subdirectories of the default root directory as a slice of strings.
Expand Down Expand Up @@ -409,6 +423,7 @@ impl DirectoryLayer {
node.retrieve_layer(&trx).await?;

if let Some(fdb_slice) = trx.get(node.node_subspace.bytes(), false).await? {
println!("found something in {:?}", node.node_subspace.to_owned());
node.content_subspace = Some(Subspace::from_bytes(&*fdb_slice));
}

Expand Down
29 changes: 25 additions & 4 deletions foundationdb/src/directory/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,36 @@ impl Node {
}

/// delete subspace from the node_subspace
pub(crate) async fn delete_content_subspace(
&mut self,
pub(crate) async fn delete_content_from_node_subspace(
&self,
trx: &Transaction,
) -> Result<(), DirectoryError> {
let key = self.node_subspace.to_owned();
trx.clear(key.bytes());
println!(
"deleting node_subspace {:?}",
&self.node_subspace.to_owned()
);
trx.clear(&self.node_subspace.bytes());
//trx.clear_subspace_range(&self.node_subspace.to_owned());
Ok(())
}

pub(crate) async fn delete_content_from_content_subspace(
&self,
trx: &Transaction,
) -> Result<(), DirectoryError> {
match self.content_subspace.to_owned() {
None => Ok(()),
Some(subspace) => {
println!(
"deleting content_subspace {:?}",
&self.content_subspace.to_owned()
);
trx.clear_subspace_range(&subspace);
Ok(())
}
}
}

/// retrieve the layer used for this node
pub(crate) async fn retrieve_layer(&mut self, trx: &Transaction) -> Result<(), FdbError> {
if self.layer == None {
Expand Down
141 changes: 139 additions & 2 deletions foundationdb/tests/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use foundationdb::*;
mod common;

#[test]
fn test_directory() {
fn test_create_or_open_directory() {
let _guard = unsafe { foundationdb::boot() };
let db = futures::executor::block_on(common::database()).expect("cannot open fdb");

Expand Down Expand Up @@ -49,12 +49,63 @@ fn test_directory() {
.expect("failed to run");

futures::executor::block_on(test_bad_layer(&db)).expect("failed to run");
}

#[test]
fn test_delete() {
let _guard = unsafe { foundationdb::boot() };
let db = futures::executor::block_on(common::database()).expect("cannot open fdb");

eprintln!("clearing all keys");
let trx = db.create_trx().expect("cannot create txn");
trx.clear_range(b"", b"\xff");
futures::executor::block_on(trx.commit()).expect("could not clear keys");

eprintln!("creating directories");
let directory = DirectoryLayer::default();

// test deletions, first we need to create it
futures::executor::block_on(test_create_or_open_async(
&db,
&directory,
vec![String::from("deletion")],
))
.expect("failed to run");
// then delete it
futures::executor::block_on(test_delete_async(
&db,
&directory,
vec![String::from("deletion")],
))
.expect("failed to run");

futures::executor::block_on(test_create_then_delete(
&db,
&directory,
vec![String::from("n0")],
1,
))
.expect("failed to run");
}

#[test]
fn test_move() {
let _guard = unsafe { foundationdb::boot() };
let db = futures::executor::block_on(common::database()).expect("cannot open fdb");

eprintln!("clearing all keys");
let trx = db.create_trx().expect("cannot create txn");
trx.clear_range(b"", b"\xff");
futures::executor::block_on(trx.commit()).expect("could not clear keys");

eprintln!("creating directories");
let directory = DirectoryLayer::default();

futures::executor::block_on(test_create_then_move_to(
&db,
&directory,
vec![String::from("d"), String::from("e")],
vec![String::from("a"), String::from("g")],
vec![String::from("a")],
))
.expect("failed to run");

Expand Down Expand Up @@ -130,6 +181,68 @@ fn test_directory() {
}
}

async fn test_create_then_delete(
db: &Database,
directory: &DirectoryLayer,
paths: Vec<String>,
sub_path_to_create: usize,
) -> Result<(), DirectoryError> {
// creating directory
let trx = db.create_trx()?;
directory.create_or_open(&trx, paths.to_owned()).await?;

trx.commit().await.expect("could not commit");

let trx = db.create_trx()?;
let children = directory.list(&trx, paths.to_owned()).await?;
assert!(children.is_empty());
trx.commit().await.expect("could not commit");

for i in 0..sub_path_to_create {
let trx = db.create_trx()?;
let mut sub_path = paths.clone();
let path_name = format!("{}", i);
sub_path.push(path_name.to_owned());

// creating subfolders
eprintln!("creating {:?}", sub_path.to_owned());
directory.create(&trx, sub_path.to_owned()).await;
trx.commit().await.expect("could not commit");

// checking it does exists
let trx = db.create_trx()?;
eprintln!("trying to get {:?}", sub_path.to_owned());
let exists = directory.exists(&trx, sub_path.to_owned()).await?;
assert!(exists, "path {:?} should exists", sub_path.to_owned());
trx.commit().await.expect("could not commit");

let trx = db.create_trx()?;
let children = directory.list(&trx, paths.to_owned()).await?;
assert!(children.contains(&path_name.to_owned()));
trx.commit().await.expect("could not commit");

// trying to delete it
let trx = db.create_trx()?;
eprintln!("deleting {:?}", sub_path.to_owned());
let delete_result = directory.remove(&trx, sub_path.to_owned()).await?;
assert!(delete_result);
trx.commit().await.expect("could not commit");

// checking it does not exists
let trx = db.create_trx()?;
eprintln!("trying to get {:?}", sub_path.to_owned());
let exists = directory.exists(&trx, sub_path.to_owned()).await?;
assert!(!exists, "path {:?} should not exists", sub_path.to_owned());
trx.commit().await.expect("could not commit");
}
let trx = db.create_trx()?;
let children = directory.list(&trx, paths.to_owned()).await?;
assert!(children.is_empty(), "children is not empty: {:?}", children);
trx.commit().await.expect("could not commit");

Ok(())
}

async fn test_create_then_move_to(
db: &Database,
directory: &DirectoryLayer,
Expand Down Expand Up @@ -231,6 +344,30 @@ async fn test_create_or_open_async(
Ok(())
}

async fn test_delete_async(
db: &Database,
directory: &DirectoryLayer,
paths: Vec<String>,
) -> FdbResult<()> {
let trx = db.create_trx()?;
let _ = directory
.create_or_open(&trx, paths.to_owned())
.await
.expect("cannot create");
eprintln!("removing {:?}", paths.to_owned());
let delete_output = directory.remove(&trx, paths.to_owned()).await;
assert!(delete_output.is_ok());
trx.commit().await.expect("could not commit");

// checking it does not exists
let trx = db.create_trx()?;
let exists = directory.exists(&trx, paths.to_owned()).await.expect("bla");
assert!(!exists, "path {:?} should not exists", paths.to_owned());
trx.commit().await.expect("could not commit");

Ok(())
}

/// testing that we throwing Err(DirectoryError::IncompatibleLayer)
async fn test_bad_layer(db: &Database) -> Result<(), DirectoryError> {
let directory = DirectoryLayer {
Expand Down

0 comments on commit 920918a

Please sign in to comment.