@@ -19,7 +19,7 @@ use crate::directory::node::Node;
19
19
use crate :: future:: FdbSlice ;
20
20
use crate :: tuple:: hca:: HighContentionAllocator ;
21
21
use crate :: tuple:: Subspace ;
22
- use crate :: { FdbError , FdbResult , Transaction } ;
22
+ use crate :: { FdbResult , Transaction } ;
23
23
use byteorder:: { LittleEndian , WriteBytesExt } ;
24
24
25
25
// TODO: useful?
@@ -29,7 +29,7 @@ const MINOR_VERSION: u32 = 0;
29
29
const PATCH_VERSION : u32 = 0 ;
30
30
const DEFAULT_NODE_PREFIX : & [ u8 ] = b"\xFE " ;
31
31
const DEFAULT_HCA_PREFIX : & [ u8 ] = b"hca" ;
32
- const DEFAULT_SUB_DIRS : u8 = 0 ;
32
+ const DEFAULT_SUB_DIRS : i64 = 0 ;
33
33
34
34
/// An implementation of FoundationDB's directory that is compatible with other bindings.
35
35
///
@@ -205,11 +205,9 @@ impl DirectoryLayer {
205
205
trx : & Transaction ,
206
206
path : Vec < String > ,
207
207
) -> 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 )
213
211
}
214
212
215
213
/// `move_to` the directory from old_path to new_path(both relative to this
@@ -219,87 +217,21 @@ impl DirectoryLayer {
219
217
/// parent directory of newPath does not exist.
220
218
pub async fn move_to (
221
219
& 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 > ,
225
223
) -> 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 ! ( )
279
225
}
280
226
281
227
/// `remove` the subdirectory of this Directory located at `path` and all of its subdirectories,
282
228
/// as well as all of their contents.
283
229
pub async fn remove (
284
230
& self ,
285
- trx : & Transaction ,
286
- path : Vec < String > ,
231
+ _trx : & Transaction ,
232
+ _path : Vec < String > ,
287
233
) -> 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 ! ( )
303
235
}
304
236
305
237
/// `list` returns the names of the immediate subdirectories of the default root directory as a slice of strings.
@@ -309,12 +241,8 @@ impl DirectoryLayer {
309
241
trx : & Transaction ,
310
242
path : Vec < String > ,
311
243
) -> 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
318
246
}
319
247
320
248
/// `create_or_open_internal` is the function used to open and/or create a directory.
@@ -340,64 +268,20 @@ impl DirectoryLayer {
340
268
return Err ( DirectoryError :: NoPathProvided ) ;
341
269
}
342
270
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 ) ;
380
276
}
381
- Some ( subspace) => {
382
- parent_subspace = subspace. clone ( ) ;
277
+
278
+ if !self . layer . is_empty ( ) {
279
+ node. check_layer ( self . layer . to_owned ( ) ) ?;
383
280
}
384
- }
385
- }
386
281
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 ( ) )
400
283
}
284
+ Err ( err) => Err ( err) ,
401
285
}
402
286
}
403
287
@@ -454,56 +338,74 @@ impl DirectoryLayer {
454
338
value. write_u32 :: < LittleEndian > ( MINOR_VERSION ) . unwrap ( ) ;
455
339
value. write_u32 :: < LittleEndian > ( PATCH_VERSION ) . unwrap ( ) ;
456
340
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) ;
458
342
trx. set ( directory_version_key. bytes ( ) , & value) ;
459
343
460
344
Ok ( ( ) )
461
345
}
462
346
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 (
468
348
& self ,
469
349
trx : & Transaction ,
470
350
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
+ } ;
476
359
let mut node_path = vec ! [ ] ;
477
360
478
361
for path_name in path {
479
362
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
+ } ;
484
382
485
- let mut node = Node {
383
+ node = Node {
486
384
path : node_path. clone ( ) ,
487
385
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 ( ) ) ) ,
490
388
} ;
491
389
492
390
node. retrieve_layer ( & trx) . await ?;
493
391
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 ( ) ) ;
496
394
}
497
-
498
- nodes. push ( node) ;
499
395
}
500
396
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 ( ) ) ;
502
404
}
503
405
504
406
async fn get_version_value ( & self , trx : & Transaction ) -> FdbResult < Option < FdbSlice > > {
505
407
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) ;
507
409
trx. get ( version_key. bytes ( ) , false ) . await
508
410
}
509
411
}
0 commit comments