Skip to content

Commit 0827de0

Browse files
committed
feat(foundationdb): implement Directory.list
1 parent c23114b commit 0827de0

File tree

4 files changed

+94
-1
lines changed

4 files changed

+94
-1
lines changed

foundationdb/src/directory/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1111
use crate::error;
1212
use crate::tuple::hca::HcaError;
13+
use crate::tuple::PackError;
1314
use std::io;
1415

1516
/// The enumeration holding all possible errors from a Directory.
@@ -29,6 +30,7 @@ pub enum DirectoryError {
2930
IoError(io::Error),
3031
FdbError(error::FdbError),
3132
HcaError(HcaError),
33+
PackError(PackError),
3234
}
3335

3436
impl From<error::FdbError> for DirectoryError {
@@ -42,3 +44,9 @@ impl From<HcaError> for DirectoryError {
4244
DirectoryError::HcaError(err)
4345
}
4446
}
47+
48+
impl From<PackError> for DirectoryError {
49+
fn from(err: PackError) -> Self {
50+
DirectoryError::PackError(err)
51+
}
52+
}

foundationdb/src/directory/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,20 @@ impl DirectoryLayer {
138138
.await
139139
}
140140

141+
/// list all sub-directory contained in the path
142+
pub async fn list(
143+
&self,
144+
trx: &Transaction,
145+
paths: Vec<String>,
146+
) -> Result<Vec<String>, DirectoryError> {
147+
let nodes = self.find_nodes(trx, paths.to_owned()).await?;
148+
149+
match nodes.last() {
150+
None => Err(DirectoryError::DirNotExists),
151+
Some(node) => node.list(&trx).await,
152+
}
153+
}
154+
141155
async fn create_or_open_internal(
142156
&self,
143157
trx: &Transaction,

foundationdb/src/directory/node.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
use crate::directory::DirectoryError;
1010
use crate::tuple::Subspace;
11-
use crate::{FdbError, Transaction};
11+
use crate::{FdbError, RangeOption, Transaction};
1212

1313
/// Node are used to represent the paths generated by a Directory.
1414
/// They are stored in the `Directory.`
@@ -64,4 +64,37 @@ impl Node {
6464
}
6565
Ok(())
6666
}
67+
68+
/// list sub-folders for a node
69+
pub(crate) async fn list(&self, trx: &Transaction) -> Result<Vec<String>, DirectoryError> {
70+
let mut results = vec![];
71+
72+
let range_option = RangeOption::from(&self.node_subspace.to_owned());
73+
74+
let fdb_values = trx.get_range(&range_option, 1_024, false).await?;
75+
76+
for fdb_value in fdb_values {
77+
let subspace = Subspace::from_bytes(fdb_value.key());
78+
// stripping from subspace
79+
let sub_directory: Vec<u8> = self.node_subspace.unpack(subspace.bytes())?;
80+
match String::from_utf8(sub_directory.to_owned()) {
81+
Ok(mut s) => {
82+
// s is like "\u{0}\u{2}node-0\u{0}"
83+
// we need to remove DEFAULT_SUB_DIRS at the beginning and the padding at the end.
84+
// maybe there is a better way to clean it? Unpack?
85+
s.remove(0);
86+
s.remove(0);
87+
s.remove(s.len() - 1);
88+
results.push(s);
89+
}
90+
Err(err) => {
91+
return Err(DirectoryError::Message(format!(
92+
"could not decode '{:?}' in utf-8: {}",
93+
sub_directory, err
94+
)))
95+
}
96+
}
97+
}
98+
Ok(results)
99+
}
67100
}

foundationdb/tests/directory.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ fn test_directory() {
3838
))
3939
.expect("failed to run");
4040

41+
futures::executor::block_on(test_list(&db, &directory, vec![String::from("a")], 10))
42+
.expect("failed to run");
43+
4144
futures::executor::block_on(test_bad_layer(&db)).expect("failed to run");
4245
}
4346

@@ -99,3 +102,38 @@ async fn test_bad_layer(db: &Database) -> Result<(), DirectoryError> {
99102

100103
Ok(())
101104
}
105+
106+
async fn test_list(
107+
db: &Database,
108+
directory: &DirectoryLayer,
109+
paths: Vec<String>,
110+
sub_path_to_create: usize,
111+
) -> Result<(), DirectoryError> {
112+
// creating directory
113+
let trx = db.create_trx()?;
114+
directory.create(&trx, paths.to_owned()).await;
115+
trx.commit().await.expect("could not commit");
116+
117+
for i in 0..sub_path_to_create {
118+
let trx = db.create_trx()?;
119+
120+
let mut sub_path = paths.clone();
121+
sub_path.push(format!("node-{}", i));
122+
eprintln!("creating {:?}", sub_path.to_owned());
123+
directory.create(&trx, sub_path.to_owned()).await;
124+
125+
trx.commit().await.expect("could not commit");
126+
}
127+
128+
let trx = db.create_trx()?;
129+
130+
let sub_folders = directory.list(&trx, paths.to_owned()).await?;
131+
eprintln!("found {:?}", sub_folders);
132+
assert_eq!(sub_folders.len(), sub_path_to_create);
133+
134+
for i in 0..sub_path_to_create {
135+
assert!(sub_folders.contains(&format!("node-{}", i)));
136+
}
137+
138+
Ok(())
139+
}

0 commit comments

Comments
 (0)