@@ -22,6 +22,7 @@ use crate::tuple::Subspace;
2222use crate :: { FdbError , FdbResult , Transaction } ;
2323use byteorder:: { LittleEndian , WriteBytesExt } ;
2424
25+ // TODO: useful?
2526const _LAYER_VERSION: ( u8 , u8 , u8 ) = ( 1 , 0 , 0 ) ;
2627const MAJOR_VERSION : u32 = 1 ;
2728const MINOR_VERSION : u32 = 0 ;
@@ -73,19 +74,58 @@ const DEFAULT_SUB_DIRS: u8 = 0;
7374/// futures::executor::block_on(async_main()).expect("failed to run");
7475/// drop(network);
7576/// ```
77+ /// ## How it works
78+ ///
79+ /// Here's what will be generated when using the Directory to create a path `/app/my-app`:
80+ ///
81+ /// ```text
82+ /// +
83+ /// |
84+ /// | version = (1,0,0) # Directory's version
85+ /// |
86+ /// | +
87+ /// | "hca"| # used to allocate numbers like 12 and 42
88+ /// | +
89+ /// \xFE |
90+ /// node's | (0,"app")=12 # id allocated by the hca for "path"
91+ /// subspace | (0,"app","layer")="" # layer allow an ownership's mecanism
92+ /// |
93+ /// |
94+ /// | (0,"app",0,"my-app","layer")="" # layer allow an ownership's mecanism
95+ /// | (0,"app",0,"my-app")=42 # id allocated by the hca for "layer"
96+ /// +
97+ //
98+ ///
99+ /// +
100+ /// |
101+ /// |
102+ /// (12,42) |
103+ /// content | # data's subspace for path "app","my-app"
104+ /// subspace |
105+ /// |
106+ /// +
107+ /// ```
108+ /// In this schema:
109+ ///
110+ /// * vertical lines represents `Subspaces`,
111+ /// * `()` `Tuples`,
112+ /// * `#` comments.
113+ ///
76114pub struct DirectoryLayer {
77- /// the subspace used to store nodes.
115+ /// the subspace used to store the hierarchy of paths. Each path is composed of Nodes.
116+ /// Default is `Subspace::all()`.
78117 pub node_subspace : Subspace ,
79118 /// the subspace used to actually store the data.
119+ /// Default is `Subspace::from_bytes(b"\xFE")`
80120 pub content_subspace : Subspace ,
81121
82- /// The allocator used to generates i64 paths to shorten keys
122+ /// The allocator used to generates i64 paths that will reduce keys's length.
123+ /// Default HAC is using `Subspace::from_bytes(b"hca")` as the subspace.
83124 pub allocator : HighContentionAllocator ,
84125
85126 pub allow_manual_prefixes : bool ,
86127
87128 pub path : Vec < String > ,
88-
89129 /// This is set at node creation time and never mutated by the directory layer.
90130 /// If a layer is provided when opening nodes it checks to see that the layer matches nodes that are read.
91131 /// When there's a mismatch an error is thrown.
@@ -104,62 +144,62 @@ impl Default for DirectoryLayer {
104144 Subspace :: from_bytes ( DEFAULT_NODE_PREFIX ) . subspace ( & DEFAULT_HCA_PREFIX ) ,
105145 ) ,
106146 allow_manual_prefixes : false ,
107- path : vec ! [ ] ,
108147 layer : vec ! [ ] ,
148+ path : vec ! [ ] ,
109149 }
110150 }
111151}
112152
113153impl DirectoryLayer {
114- /// CreateOrOpen opens the directory specified by path (relative to this
154+ /// ` CreateOrOpen` opens the directory specified by path (relative to this
115155 /// Directory), and returns the directory and its contents as a
116156 /// Subspace. If the directory does not exist, it is created
117157 /// (creating parent directories if necessary).
118158 pub async fn create_or_open (
119159 & self ,
120160 txn : & Transaction ,
121- paths : Vec < String > ,
161+ path : Vec < String > ,
122162 ) -> Result < Subspace , DirectoryError > {
123- self . create_or_open_internal ( txn, paths , vec ! [ ] , true , true )
163+ self . create_or_open_internal ( txn, path , vec ! [ ] , true , true )
124164 . await
125165 }
126166
127- /// Create creates a directory specified by path (relative to this
167+ /// ` Create` creates a directory specified by path (relative to this
128168 /// Directory), and returns the directory and its contents as a
129169 /// Subspace (or ErrDirAlreadyExists if the directory already exists).
130- pub async fn create ( & self , txn : & Transaction , paths : Vec < String > ) -> Option < DirectoryError > {
131- self . create_or_open_internal ( txn, paths , vec ! [ ] , true , false )
170+ pub async fn create ( & self , txn : & Transaction , path : Vec < String > ) -> Option < DirectoryError > {
171+ self . create_or_open_internal ( txn, path , vec ! [ ] , true , false )
132172 . await
133173 . err ( )
134174 }
135175
136- /// Open opens the directory specified by path (relative to this Directory),
176+ /// ` Open` opens the directory specified by path (relative to this Directory),
137177 /// and returns the directory and its contents as a Subspace (or Err(DirNotExists)
138178 /// error if the directory does not exist, or ErrParentDirDoesNotExist if one of the parent
139179 /// directories in the path does not exist).
140180 pub async fn open (
141181 & self ,
142182 txn : & Transaction ,
143- paths : Vec < String > ,
183+ path : Vec < String > ,
144184 ) -> Result < Subspace , DirectoryError > {
145- self . create_or_open_internal ( txn, paths , vec ! [ ] , false , true )
185+ self . create_or_open_internal ( txn, path , vec ! [ ] , false , true )
146186 . await
147187 }
148188
149- /// Exists returns true if the directory at path (relative to the default root directory) exists, and false otherwise.
189+ /// ` Exists` returns true if the directory at path (relative to the default root directory) exists, and false otherwise.
150190 pub async fn exists (
151191 & self ,
152192 trx : & Transaction ,
153- paths : Vec < String > ,
193+ path : Vec < String > ,
154194 ) -> Result < bool , DirectoryError > {
155- let nodes = self . find_nodes ( trx, paths . to_owned ( ) ) . await ?;
195+ let nodes = self . find_nodes ( trx, path . to_owned ( ) ) . await ?;
156196 match nodes. last ( ) {
157197 None => Ok ( false ) ,
158198 Some ( node) => Ok ( node. content_subspace . is_some ( ) ) ,
159199 }
160200 }
161201
162- /// Move moves the directory at oldPath to newPath (both relative to this
202+ /// ` Move moves` the directory from old_path to new_path (both relative to this
163203 /// Directory), and returns the directory (at its new location) and its
164204 /// contents as a Subspace. Move will return an error if a directory
165205 /// does not exist at oldPath, a directory already exists at newPath, or the
@@ -169,7 +209,7 @@ impl DirectoryLayer {
169209 trx : & Transaction ,
170210 old_path : Vec < String > ,
171211 new_path : Vec < String > ,
172- ) -> Result < bool , DirectoryError > {
212+ ) -> Result < Subspace , DirectoryError > {
173213 self . check_version ( trx, false ) . await ?;
174214
175215 if old_path. is_empty ( ) || new_path. is_empty ( ) {
@@ -182,14 +222,14 @@ impl DirectoryLayer {
182222
183223 let mut old_nodes = self . find_nodes ( & trx, old_path. to_owned ( ) ) . await ?;
184224 let last_node_from_old_path = match old_nodes. last_mut ( ) {
185- None => return Err ( DirectoryError :: Message ( String :: from ( "empty path" ) ) ) ,
225+ None => return Err ( DirectoryError :: PathDoesNotExists ) ,
186226 Some ( node) => node,
187227 } ;
188228
189229 let content_subspace = last_node_from_old_path
190230 . content_subspace
191231 . as_ref ( )
192- . ok_or ( DirectoryError :: DirNotExists ) ?;
232+ . ok_or ( DirectoryError :: PathDoesNotExists ) ?;
193233
194234 let mut new_nodes = self . find_nodes ( & trx, new_path. to_owned ( ) ) . await ?;
195235
@@ -205,7 +245,7 @@ impl DirectoryLayer {
205245 }
206246
207247 let last_node_from_new_path = match new_nodes. last_mut ( ) {
208- None => return Err ( DirectoryError :: Message ( String :: from ( "empty path" ) ) ) ,
248+ None => return Err ( DirectoryError :: PathDoesNotExists ) ,
209249 Some ( node) => {
210250 if node. content_subspace . is_some ( ) {
211251 return Err ( DirectoryError :: DirAlreadyExists ) ;
@@ -222,7 +262,7 @@ impl DirectoryLayer {
222262 . delete_content_from_node_subspace ( & trx)
223263 . await ?;
224264
225- Ok ( true )
265+ Ok ( content_subspace . to_owned ( ) )
226266 }
227267
228268 /// `Remove` the subdirectory of this Directory located at `path` and all of its subdirectories,
@@ -242,33 +282,33 @@ impl DirectoryLayer {
242282 match nodes. last ( ) {
243283 None => Ok ( false ) ,
244284 Some ( node) => {
245- println ! ( "found a node to delete: {:?}" , node) ;
246285 node. delete_content_from_node_subspace ( & trx) . await ?;
247286 node. delete_content_from_content_subspace ( & trx) . await ?;
248287 Ok ( true )
249288 }
250289 }
251290 }
252291
253- /// List returns the names of the immediate subdirectories of the default root directory as a slice of strings.
292+ /// ` List` returns the names of the immediate subdirectories of the default root directory as a slice of strings.
254293 /// Each string is the name of the last component of a subdirectory's path.
255294 pub async fn list (
256295 & self ,
257296 trx : & Transaction ,
258- paths : Vec < String > ,
297+ path : Vec < String > ,
259298 ) -> Result < Vec < String > , DirectoryError > {
260- let nodes = self . find_nodes ( trx, paths . to_owned ( ) ) . await ?;
299+ let nodes = self . find_nodes ( trx, path . to_owned ( ) ) . await ?;
261300
262301 match nodes. last ( ) {
263- None => Err ( DirectoryError :: DirNotExists ) ,
302+ None => Err ( DirectoryError :: PathDoesNotExists ) ,
264303 Some ( node) => node. list ( & trx) . await ,
265304 }
266305 }
267306
307+ /// `create_or_open_internal` is the function used to open and/or create a directory.
268308 async fn create_or_open_internal (
269309 & self ,
270310 trx : & Transaction ,
271- paths : Vec < String > ,
311+ path : Vec < String > ,
272312 prefix : Vec < u8 > ,
273313 allow_create : bool ,
274314 allow_open : bool ,
@@ -277,21 +317,17 @@ impl DirectoryLayer {
277317
278318 if !prefix. is_empty ( ) && !self . allow_manual_prefixes {
279319 if self . path . is_empty ( ) {
280- return Err ( DirectoryError :: Message (
281- "cannot specify a prefix unless manual prefixes are enabled" . to_string ( ) ,
282- ) ) ;
320+ return Err ( DirectoryError :: PrefixNotAllowed ) ;
283321 }
284322
285- return Err ( DirectoryError :: Message (
286- "cannot specify a prefix in a partition" . to_string ( ) ,
287- ) ) ;
323+ return Err ( DirectoryError :: CannotPrefixInPartition ) ;
288324 }
289325
290- if paths . is_empty ( ) {
326+ if path . is_empty ( ) {
291327 return Err ( DirectoryError :: NoPathProvided ) ;
292328 }
293329
294- let nodes = self . find_nodes ( trx, paths . to_owned ( ) ) . await ?;
330+ let nodes = self . find_nodes ( trx, path . to_owned ( ) ) . await ?;
295331
296332 let last_node = nodes. last ( ) . expect ( "could not contain 0 nodes" ) ;
297333
@@ -313,7 +349,7 @@ impl DirectoryLayer {
313349
314350 // at least one node does not exists, we need to create them
315351 if !allow_create {
316- return Err ( DirectoryError :: DirNotExists ) ;
352+ return Err ( DirectoryError :: PathDoesNotExists ) ;
317353 }
318354
319355 let mut parent_subspace = self . content_subspace . clone ( ) ;
@@ -333,7 +369,7 @@ impl DirectoryLayer {
333369 Ok ( parent_subspace)
334370 }
335371
336- /// checks the version of the directory within FDB
372+ /// `check_version` is checking the Directory's version in FDB.
337373 async fn check_version (
338374 & self ,
339375 trx : & Transaction ,
@@ -345,7 +381,7 @@ impl DirectoryLayer {
345381 if allow_creation {
346382 self . initialize_directory ( trx) . await
347383 } else {
348- Err ( DirectoryError :: DirNotExists )
384+ Err ( DirectoryError :: MissingDirectory )
349385 }
350386 }
351387 Some ( versions) => {
@@ -379,6 +415,7 @@ impl DirectoryLayer {
379415 }
380416 }
381417
418+ /// `initialize_directory` is initializing the directory
382419 async fn initialize_directory ( & self , trx : & Transaction ) -> Result < ( ) , DirectoryError > {
383420 let mut value = vec ! [ ] ;
384421 value. write_u32 :: < LittleEndian > ( MAJOR_VERSION ) . unwrap ( ) ;
@@ -398,23 +435,23 @@ impl DirectoryLayer {
398435 async fn find_nodes (
399436 & self ,
400437 trx : & Transaction ,
401- paths : Vec < String > ,
438+ path : Vec < String > ,
402439 ) -> Result < Vec < Node > , FdbError > {
403440 let mut nodes = vec ! [ ] ;
404441
405442 let mut subspace = self . node_subspace . to_owned ( ) ;
406443
407444 let mut node_path = vec ! [ ] ;
408445
409- for path_name in paths {
446+ for path_name in path {
410447 node_path. push ( path_name. to_owned ( ) ) ;
411448 subspace = subspace. subspace :: < ( & [ u8 ] , String ) > ( & (
412449 vec ! [ DEFAULT_SUB_DIRS ] . as_slice ( ) ,
413450 path_name. to_owned ( ) ,
414451 ) ) ;
415452
416453 let mut node = Node {
417- paths : node_path. clone ( ) ,
454+ path : node_path. clone ( ) ,
418455 layer : None ,
419456 node_subspace : subspace. to_owned ( ) ,
420457 content_subspace : None ,
@@ -423,7 +460,6 @@ impl DirectoryLayer {
423460 node. retrieve_layer ( & trx) . await ?;
424461
425462 if let Some ( fdb_slice) = trx. get ( node. node_subspace . bytes ( ) , false ) . await ? {
426- println ! ( "found something in {:?}" , node. node_subspace. to_owned( ) ) ;
427463 node. content_subspace = Some ( Subspace :: from_bytes ( & * fdb_slice) ) ;
428464 }
429465
0 commit comments