@@ -19,7 +19,7 @@ use crate::directory::node::Node;
1919use crate :: future:: FdbSlice ;
2020use crate :: tuple:: hca:: HighContentionAllocator ;
2121use crate :: tuple:: Subspace ;
22- use crate :: { FdbError , FdbResult , Transaction } ;
22+ use crate :: { FdbResult , Transaction } ;
2323use byteorder:: { LittleEndian , WriteBytesExt } ;
2424
2525// TODO: useful?
@@ -29,7 +29,7 @@ const MINOR_VERSION: u32 = 0;
2929const PATCH_VERSION : u32 = 0 ;
3030const DEFAULT_NODE_PREFIX : & [ u8 ] = b"\xFE " ;
3131const DEFAULT_HCA_PREFIX : & [ u8 ] = b"hca" ;
32- const DEFAULT_SUB_DIRS : u8 = 0 ;
32+ const DEFAULT_SUB_DIRS : i64 = 0 ;
3333
3434/// An implementation of FoundationDB's directory that is compatible with other bindings.
3535///
@@ -205,11 +205,9 @@ impl DirectoryLayer {
205205 trx : & Transaction ,
206206 path : Vec < String > ,
207207 ) -> Result < bool , DirectoryError > {
208- let nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
209- match nodes. last ( ) {
210- None => Ok ( false ) ,
211- Some ( node) => Ok ( node. content_subspace . is_some ( ) ) ,
212- }
208+ self . find_node ( trx, path. to_owned ( ) , false )
209+ . await
210+ . map ( |_| true )
213211 }
214212
215213 /// `move_to` the directory from old_path to new_path(both relative to this
@@ -219,87 +217,21 @@ impl DirectoryLayer {
219217 /// parent directory of newPath does not exist.
220218 pub async fn move_to (
221219 & self ,
222- trx : & Transaction ,
223- old_path : Vec < String > ,
224- new_path : Vec < String > ,
220+ _trx : & Transaction ,
221+ _old_path : Vec < String > ,
222+ _new_path : Vec < String > ,
225223 ) -> Result < Subspace , DirectoryError > {
226- self . check_version ( trx, false ) . await ?;
227-
228- if old_path. is_empty ( ) || new_path. is_empty ( ) {
229- return Err ( DirectoryError :: NoPathProvided ) ;
230- }
231-
232- if new_path. starts_with ( old_path. as_slice ( ) ) {
233- return Err ( DirectoryError :: BadDestinationDirectory ) ;
234- }
235-
236- let mut old_nodes = self . find_nodes ( & trx, old_path. to_owned ( ) ) . await ?;
237- let last_node_from_old_path = match old_nodes. last_mut ( ) {
238- None => return Err ( DirectoryError :: PathDoesNotExists ) ,
239- Some ( node) => node,
240- } ;
241-
242- let content_subspace = last_node_from_old_path
243- . content_subspace
244- . as_ref ( )
245- . ok_or ( DirectoryError :: PathDoesNotExists ) ?;
246-
247- let mut new_nodes = self . find_nodes ( & trx, new_path. to_owned ( ) ) . await ?;
248-
249- // assert that parent of the new node exists
250- if new_nodes. len ( ) >= 2 {
251- match new_nodes. get ( new_nodes. len ( ) - 2 ) {
252- None => { }
253- Some ( parent_node) => match parent_node. content_subspace {
254- None => return Err ( DirectoryError :: ParentDirDoesNotExists ) ,
255- Some ( _) => { }
256- } ,
257- }
258- }
259-
260- let last_node_from_new_path = match new_nodes. last_mut ( ) {
261- None => return Err ( DirectoryError :: PathDoesNotExists ) ,
262- Some ( node) => {
263- if node. content_subspace . is_some ( ) {
264- return Err ( DirectoryError :: DirAlreadyExists ) ;
265- }
266- node
267- }
268- } ;
269-
270- last_node_from_new_path
271- . persist_content_subspace ( & trx, content_subspace. to_owned ( ) )
272- . await ?;
273-
274- last_node_from_old_path
275- . delete_content_from_node_subspace ( & trx)
276- . await ?;
277-
278- Ok ( content_subspace. to_owned ( ) )
224+ unimplemented ! ( )
279225 }
280226
281227 /// `remove` the subdirectory of this Directory located at `path` and all of its subdirectories,
282228 /// as well as all of their contents.
283229 pub async fn remove (
284230 & self ,
285- trx : & Transaction ,
286- path : Vec < String > ,
231+ _trx : & Transaction ,
232+ _path : Vec < String > ,
287233 ) -> Result < bool , DirectoryError > {
288- self . check_version ( trx, false ) . await ?;
289- if path. is_empty ( ) {
290- return Err ( DirectoryError :: NoPathProvided ) ;
291- }
292-
293- let nodes = self . find_nodes ( & trx, path. to_owned ( ) ) . await ?;
294-
295- match nodes. last ( ) {
296- None => Ok ( false ) ,
297- Some ( node) => {
298- node. delete_content_from_node_subspace ( & trx) . await ?;
299- node. delete_content_from_content_subspace ( & trx) . await ?;
300- Ok ( true )
301- }
302- }
234+ unimplemented ! ( )
303235 }
304236
305237 /// `list` returns the names of the immediate subdirectories of the default root directory as a slice of strings.
@@ -309,12 +241,8 @@ impl DirectoryLayer {
309241 trx : & Transaction ,
310242 path : Vec < String > ,
311243 ) -> Result < Vec < String > , DirectoryError > {
312- let nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
313-
314- match nodes. last ( ) {
315- None => Err ( DirectoryError :: PathDoesNotExists ) ,
316- Some ( node) => node. list ( & trx) . await ,
317- }
244+ let node = self . find_node ( trx, path. to_owned ( ) , false ) . await ?;
245+ node. list ( & trx) . await
318246 }
319247
320248 /// `create_or_open_internal` is the function used to open and/or create a directory.
@@ -340,64 +268,20 @@ impl DirectoryLayer {
340268 return Err ( DirectoryError :: NoPathProvided ) ;
341269 }
342270
343- let mut nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
344-
345- let last_node = nodes. last ( ) . expect ( "could not contain 0 nodes" ) ;
346-
347- // if the node_subspace of the last element exists, then we do not need to create anything
348- // and we can return it directly
349- if last_node. content_subspace . is_some ( ) {
350- let node = nodes. last ( ) . expect ( "could not contain 0 node" ) ;
351-
352- if !allow_open {
353- return Err ( DirectoryError :: DirAlreadyExists ) ;
354- }
355-
356- if !self . layer . is_empty ( ) {
357- node. check_layer ( self . layer . to_owned ( ) ) ?;
358- }
359-
360- return Ok ( node. content_subspace . clone ( ) . unwrap ( ) ) ;
361- }
362-
363- // at least one node does not exists, we need to create them
364- if !allow_create {
365- return Err ( DirectoryError :: PathDoesNotExists ) ;
366- }
367-
368- let ( last, parent_nodes) = nodes. split_last_mut ( ) . expect ( "already checked" ) ;
369-
370- // let's create parents first.
371- let mut parent_subspace = self . content_subspace . clone ( ) ;
372- for parent_node in parent_nodes {
373- match & parent_node. content_subspace {
374- None => {
375- // creating subspace
376- let allocator = self . allocator . allocate ( trx) . await ?;
377- parent_subspace = parent_node
378- . create_and_write_content_subspace ( & trx, allocator, & parent_subspace)
379- . await ?;
271+ match self . find_node ( & trx, path. to_owned ( ) , allow_create) . await {
272+ Ok ( node) => {
273+ // node exists, checking layer
274+ if !allow_open {
275+ return Err ( DirectoryError :: DirAlreadyExists ) ;
380276 }
381- Some ( subspace) => {
382- parent_subspace = subspace. clone ( ) ;
277+
278+ if !self . layer . is_empty ( ) {
279+ node. check_layer ( self . layer . to_owned ( ) ) ?;
383280 }
384- }
385- }
386281
387- // parents are created, let's create the final node
388- match prefix {
389- None => {
390- let allocator = self . allocator . allocate ( trx) . await ?;
391- parent_subspace = last
392- . create_and_write_content_subspace ( & trx, allocator, & parent_subspace)
393- . await ?;
394- Ok ( parent_subspace)
395- }
396- Some ( prefix) => {
397- last. persist_prefix_as_content_subspace ( & trx, prefix. to_owned ( ) )
398- . await ?;
399- Ok ( Subspace :: from_bytes ( prefix. as_ref ( ) ) )
282+ Ok ( node. content_subspace . clone ( ) . unwrap ( ) )
400283 }
284+ Err ( err) => Err ( err) ,
401285 }
402286 }
403287
@@ -454,56 +338,74 @@ impl DirectoryLayer {
454338 value. write_u32 :: < LittleEndian > ( MINOR_VERSION ) . unwrap ( ) ;
455339 value. write_u32 :: < LittleEndian > ( PATCH_VERSION ) . unwrap ( ) ;
456340 let version_subspace: & [ u8 ] = b"version" ;
457- let directory_version_key = self . node_subspace . subspace ( & version_subspace) ;
341+ let directory_version_key = self . get_root_node_subspace ( ) . subspace ( & version_subspace) ;
458342 trx. set ( directory_version_key. bytes ( ) , & value) ;
459343
460344 Ok ( ( ) )
461345 }
462346
463- /// walk is crawling the node_subspace and searching for the nodes.
464- /// It returns a Vec of `Node`, each node represents an element of the paths provided.
465- ///
466- /// If all paths are already existing, then the last node will have the content_subspace set.
467- async fn find_nodes (
347+ async fn find_node (
468348 & self ,
469349 trx : & Transaction ,
470350 path : Vec < String > ,
471- ) -> Result < Vec < Node > , FdbError > {
472- let mut nodes = vec ! [ ] ;
473-
474- let mut subspace = self . node_subspace . to_owned ( ) ;
475-
351+ allow_creation : bool ,
352+ ) -> Result < Node , DirectoryError > {
353+ let mut node = Node {
354+ layer : None ,
355+ path : vec ! [ ] ,
356+ node_subspace : self . get_root_node_subspace ( ) ,
357+ content_subspace : None ,
358+ } ;
476359 let mut node_path = vec ! [ ] ;
477360
478361 for path_name in path {
479362 node_path. push ( path_name. to_owned ( ) ) ;
480- subspace = subspace. subspace :: < ( & [ u8 ] , String ) > ( & (
481- vec ! [ DEFAULT_SUB_DIRS ] . as_slice ( ) ,
482- path_name. to_owned ( ) ,
483- ) ) ;
363+ let key = node
364+ . node_subspace
365+ . subspace ( & ( DEFAULT_SUB_DIRS , path_name. to_owned ( ) ) ) ;
366+
367+ let ( prefix, new_node) = match trx. get ( key. bytes ( ) , false ) . await {
368+ Ok ( value) => match value {
369+ None => {
370+ if !allow_creation {
371+ return Err ( DirectoryError :: PathDoesNotExists ) ;
372+ }
373+ // creating the subspace for this not-existing node
374+ let allocator = self . allocator . allocate ( trx) . await ?;
375+ let subspace = self . content_subspace . subspace ( & allocator) ;
376+ ( subspace. bytes ( ) . to_vec ( ) , true )
377+ }
378+ Some ( fdb_slice) => ( ( & * fdb_slice) . to_vec ( ) , false ) ,
379+ } ,
380+ Err ( err) => return Err ( DirectoryError :: FdbError ( err) ) ,
381+ } ;
484382
485- let mut node = Node {
383+ node = Node {
486384 path : node_path. clone ( ) ,
487385 layer : None ,
488- node_subspace : subspace. to_owned ( ) ,
489- content_subspace : None ,
386+ node_subspace : self . node_subspace . subspace ( & prefix . as_slice ( ) ) ,
387+ content_subspace : Some ( Subspace :: from_bytes ( & prefix . as_slice ( ) ) ) ,
490388 } ;
491389
492390 node. retrieve_layer ( & trx) . await ?;
493391
494- if let Some ( fdb_slice ) = trx . get ( node . node_subspace . bytes ( ) , false ) . await ? {
495- node . content_subspace = Some ( Subspace :: from_bytes ( & * fdb_slice ) ) ;
392+ if new_node {
393+ trx . set ( key . bytes ( ) , prefix . as_slice ( ) ) ;
496394 }
497-
498- nodes. push ( node) ;
499395 }
500396
501- Ok ( nodes)
397+ Ok ( node)
398+ }
399+
400+ fn get_root_node_subspace ( & self ) -> Subspace {
401+ return self
402+ . node_subspace
403+ . subspace :: < & [ u8 ] > ( & self . node_subspace . bytes ( ) ) ;
502404 }
503405
504406 async fn get_version_value ( & self , trx : & Transaction ) -> FdbResult < Option < FdbSlice > > {
505407 let version_subspace: & [ u8 ] = b"version" ;
506- let version_key = self . node_subspace . subspace ( & version_subspace) ;
408+ let version_key = self . get_root_node_subspace ( ) . subspace ( & version_subspace) ;
507409 trx. get ( version_key. bytes ( ) , false ) . await
508410 }
509411}
0 commit comments