@@ -151,7 +151,7 @@ impl Default for DirectoryLayer {
151
151
}
152
152
153
153
impl DirectoryLayer {
154
- /// `CreateOrOpen ` opens the directory specified by path (relative to this
154
+ /// `create_or_open ` opens the directory specified by path (relative to this
155
155
/// Directory), and returns the directory and its contents as a
156
156
/// Subspace. If the directory does not exist, it is created
157
157
/// (creating parent directories if necessary).
@@ -160,20 +160,33 @@ impl DirectoryLayer {
160
160
txn : & Transaction ,
161
161
path : Vec < String > ,
162
162
) -> Result < Subspace , DirectoryError > {
163
- self . create_or_open_internal ( txn, path, vec ! [ ] , true , true )
163
+ self . create_or_open_internal ( txn, path, None , true , true )
164
164
. await
165
165
}
166
166
167
- /// `Create` creates a directory specified by path (relative to this
167
+ /// `create_or_open_with_prefix` is similar to `create_or_open`, but you can directly provide the keys
168
+ /// that will be used as the content_subspace, instead of using the allocator to allocate.
169
+ /// You must opened the directory with `allow_manual_prefixes` to do this.
170
+ pub async fn create_or_open_with_prefix (
171
+ & self ,
172
+ txn : & Transaction ,
173
+ path : Vec < String > ,
174
+ prefix : Vec < u8 > ,
175
+ ) -> Result < Subspace , DirectoryError > {
176
+ self . create_or_open_internal ( txn, path, Some ( prefix) , true , true )
177
+ . await
178
+ }
179
+
180
+ /// `create` creates a directory specified by path (relative to this
168
181
/// Directory), and returns the directory and its contents as a
169
182
/// Subspace (or ErrDirAlreadyExists if the directory already exists).
170
183
pub async fn create ( & self , txn : & Transaction , path : Vec < String > ) -> Option < DirectoryError > {
171
- self . create_or_open_internal ( txn, path, vec ! [ ] , true , false )
184
+ self . create_or_open_internal ( txn, path, None , true , false )
172
185
. await
173
186
. err ( )
174
187
}
175
188
176
- /// `Open ` opens the directory specified by path (relative to this Directory),
189
+ /// `open ` opens the directory specified by path (relative to this Directory),
177
190
/// and returns the directory and its contents as a Subspace (or Err(DirNotExists)
178
191
/// error if the directory does not exist, or ErrParentDirDoesNotExist if one of the parent
179
192
/// directories in the path does not exist).
@@ -182,11 +195,11 @@ impl DirectoryLayer {
182
195
txn : & Transaction ,
183
196
path : Vec < String > ,
184
197
) -> Result < Subspace , DirectoryError > {
185
- self . create_or_open_internal ( txn, path, vec ! [ ] , false , true )
198
+ self . create_or_open_internal ( txn, path, None , false , true )
186
199
. await
187
200
}
188
201
189
- /// `Exists ` returns true if the directory at path (relative to the default root directory) exists, and false otherwise.
202
+ /// `exists ` returns true if the directory at path (relative to the default root directory) exists, and false otherwise.
190
203
pub async fn exists (
191
204
& self ,
192
205
trx : & Transaction ,
@@ -199,7 +212,7 @@ impl DirectoryLayer {
199
212
}
200
213
}
201
214
202
- /// `Move moves ` the directory from old_path to new_path(both relative to this
215
+ /// `move_to ` the directory from old_path to new_path(both relative to this
203
216
/// Directory), and returns the directory (at its new location) and its
204
217
/// contents as a Subspace. Move will return an error if a directory
205
218
/// does not exist at oldPath, a directory already exists at newPath, or the
@@ -265,7 +278,7 @@ impl DirectoryLayer {
265
278
Ok ( content_subspace. to_owned ( ) )
266
279
}
267
280
268
- /// `Remove ` the subdirectory of this Directory located at `path` and all of its subdirectories,
281
+ /// `remove ` the subdirectory of this Directory located at `path` and all of its subdirectories,
269
282
/// as well as all of their contents.
270
283
pub async fn remove (
271
284
& self ,
@@ -289,7 +302,7 @@ impl DirectoryLayer {
289
302
}
290
303
}
291
304
292
- /// `List ` returns the names of the immediate subdirectories of the default root directory as a slice of strings.
305
+ /// `list ` returns the names of the immediate subdirectories of the default root directory as a slice of strings.
293
306
/// Each string is the name of the last component of a subdirectory's path.
294
307
pub async fn list (
295
308
& self ,
@@ -309,13 +322,13 @@ impl DirectoryLayer {
309
322
& self ,
310
323
trx : & Transaction ,
311
324
path : Vec < String > ,
312
- prefix : Vec < u8 > ,
325
+ prefix : Option < Vec < u8 > > ,
313
326
allow_create : bool ,
314
327
allow_open : bool ,
315
328
) -> Result < Subspace , DirectoryError > {
316
329
self . check_version ( trx, allow_create) . await ?;
317
330
318
- if ! prefix. is_empty ( ) && !self . allow_manual_prefixes {
331
+ if prefix. is_some ( ) && !self . allow_manual_prefixes {
319
332
if self . path . is_empty ( ) {
320
333
return Err ( DirectoryError :: PrefixNotAllowed ) ;
321
334
}
@@ -327,7 +340,7 @@ impl DirectoryLayer {
327
340
return Err ( DirectoryError :: NoPathProvided ) ;
328
341
}
329
342
330
- let nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
343
+ let mut nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
331
344
332
345
let last_node = nodes. last ( ) . expect ( "could not contain 0 nodes" ) ;
333
346
@@ -352,21 +365,40 @@ impl DirectoryLayer {
352
365
return Err ( DirectoryError :: PathDoesNotExists ) ;
353
366
}
354
367
355
- let mut parent_subspace = self . content_subspace . clone ( ) ;
368
+ let ( last , parent_nodes ) = nodes . split_last_mut ( ) . expect ( "already checked" ) ;
356
369
357
- for mut node in nodes {
358
- match node. content_subspace {
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 {
359
374
None => {
360
375
// creating subspace
361
376
let allocator = self . allocator . allocate ( trx) . await ?;
362
- parent_subspace = node
377
+ parent_subspace = parent_node
363
378
. create_and_write_content_subspace ( & trx, allocator, & parent_subspace)
364
379
. await ?;
365
380
}
366
- Some ( subspace) => parent_subspace = subspace. clone ( ) ,
381
+ Some ( subspace) => {
382
+ parent_subspace = subspace. clone ( ) ;
383
+ }
384
+ }
385
+ }
386
+
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 ( ) ) )
367
400
}
368
401
}
369
- Ok ( parent_subspace)
370
402
}
371
403
372
404
/// `check_version` is checking the Directory's version in FDB.
0 commit comments