@@ -151,7 +151,7 @@ impl Default for DirectoryLayer {
151151}
152152
153153impl 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
155155 /// Directory), and returns the directory and its contents as a
156156 /// Subspace. If the directory does not exist, it is created
157157 /// (creating parent directories if necessary).
@@ -160,20 +160,33 @@ impl DirectoryLayer {
160160 txn : & Transaction ,
161161 path : Vec < String > ,
162162 ) -> 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 )
164164 . await
165165 }
166166
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
168181 /// Directory), and returns the directory and its contents as a
169182 /// Subspace (or ErrDirAlreadyExists if the directory already exists).
170183 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 )
172185 . await
173186 . err ( )
174187 }
175188
176- /// `Open ` opens the directory specified by path (relative to this Directory),
189+ /// `open ` opens the directory specified by path (relative to this Directory),
177190 /// and returns the directory and its contents as a Subspace (or Err(DirNotExists)
178191 /// error if the directory does not exist, or ErrParentDirDoesNotExist if one of the parent
179192 /// directories in the path does not exist).
@@ -182,11 +195,11 @@ impl DirectoryLayer {
182195 txn : & Transaction ,
183196 path : Vec < String > ,
184197 ) -> 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 )
186199 . await
187200 }
188201
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.
190203 pub async fn exists (
191204 & self ,
192205 trx : & Transaction ,
@@ -199,7 +212,7 @@ impl DirectoryLayer {
199212 }
200213 }
201214
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
203216 /// Directory), and returns the directory (at its new location) and its
204217 /// contents as a Subspace. Move will return an error if a directory
205218 /// does not exist at oldPath, a directory already exists at newPath, or the
@@ -265,7 +278,7 @@ impl DirectoryLayer {
265278 Ok ( content_subspace. to_owned ( ) )
266279 }
267280
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,
269282 /// as well as all of their contents.
270283 pub async fn remove (
271284 & self ,
@@ -289,7 +302,7 @@ impl DirectoryLayer {
289302 }
290303 }
291304
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.
293306 /// Each string is the name of the last component of a subdirectory's path.
294307 pub async fn list (
295308 & self ,
@@ -309,13 +322,13 @@ impl DirectoryLayer {
309322 & self ,
310323 trx : & Transaction ,
311324 path : Vec < String > ,
312- prefix : Vec < u8 > ,
325+ prefix : Option < Vec < u8 > > ,
313326 allow_create : bool ,
314327 allow_open : bool ,
315328 ) -> Result < Subspace , DirectoryError > {
316329 self . check_version ( trx, allow_create) . await ?;
317330
318- if ! prefix. is_empty ( ) && !self . allow_manual_prefixes {
331+ if prefix. is_some ( ) && !self . allow_manual_prefixes {
319332 if self . path . is_empty ( ) {
320333 return Err ( DirectoryError :: PrefixNotAllowed ) ;
321334 }
@@ -327,7 +340,7 @@ impl DirectoryLayer {
327340 return Err ( DirectoryError :: NoPathProvided ) ;
328341 }
329342
330- let nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
343+ let mut nodes = self . find_nodes ( trx, path. to_owned ( ) ) . await ?;
331344
332345 let last_node = nodes. last ( ) . expect ( "could not contain 0 nodes" ) ;
333346
@@ -352,21 +365,40 @@ impl DirectoryLayer {
352365 return Err ( DirectoryError :: PathDoesNotExists ) ;
353366 }
354367
355- let mut parent_subspace = self . content_subspace . clone ( ) ;
368+ let ( last , parent_nodes ) = nodes . split_last_mut ( ) . expect ( "already checked" ) ;
356369
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 {
359374 None => {
360375 // creating subspace
361376 let allocator = self . allocator . allocate ( trx) . await ?;
362- parent_subspace = node
377+ parent_subspace = parent_node
363378 . create_and_write_content_subspace ( & trx, allocator, & parent_subspace)
364379 . await ?;
365380 }
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 ( ) ) )
367400 }
368401 }
369- Ok ( parent_subspace)
370402 }
371403
372404 /// `check_version` is checking the Directory's version in FDB.
0 commit comments