Being able to distinguish between Absolute and Relative paths, so that the DL API can spot common mistakes and reject invalid paths.
the FdbDirectoryLayer implementation itself wants absolute paths.
the FdbDirectorySubspace "instance" methods want relative paths.
FdbPath.Empty is the empty relative paths, mostly used to mean "no path"
FdbPath.Root is the "/" absolute path, which is now the default location for most locations.
When serialized to strings, absolute paths have a leading '/' literal, while relative paths do not
Embed the layer id of directories right into the path itself, and not as an extra argument only for the leaf.
a path "segment" will thus be a pair of the name of the directory node, and an optional layer id.
ex: "/Foo[partition]/ACME/Users[SomeLayer]" represents the path to a directory "Users" handled by 'SomeLayer', which is nested under the "Foo" partition.
when recursively creating missing parents, the DL can now create them with the correct layer id (esp. for partitions!)
fix issue when creating in the above example, the "Foo" partition was deleted at some point, but another tool would want to CreateAsync("/Foo/ACME/Users", "SomeLayer") and end up with "Foo" being a regular directory and not a partition. Then, subsequent attempts to open Foo as a partition would fail (because now its layer id is empty instead of "partition").
since layers have to be represented as string, their base type has been changed from Slice to string, which are encoded as utf-8 byte strings in the database.
rules for escaping are that '\' is the escape literal, and any instance of /, \, [ and ] have to be escaped with a leading \.
Reduce the risks of mixing "formatted" paths (like "/Foo/Bar/Baz") and just the directory name ("Foo") for APIs that take strings as argument.
Introduce the FdbPathSegment struct that represents a segment, and FdbPath is now a collection of these structs.
Have factory methods to create path segments from the (name, layer), or parse it from a "formatted string".
This PR also fixes a few issues and bugs in the DL that were found while refactoring:
Some bugs when Moving or Renaming partitions: the prefix of a partition would be changed when renamed, with an extra \xFE byte appended to it.
The root path ("/") would be considered a regular directory instead of a "partition", though this is only to be in synch with the rest, because a subspace or partition with the empty prefix are virtually the same thing.
Renaming FdbDirectoryPath to FdbPath is primary to reduce the length of the type, but also to force a code review of any use of that type in the application, to make sure that it is the correct type (absolute vs relative), and that it correctly includes any Layer Id.
This pull request has several objectives, mainly to fix some long-standing issues and also little API annoyances.
These issues are explained in https://forums.foundationdb.org/t/most-common-issues-or-annoyances-when-using-the-directory-layer/2096
They are:
FdbPath.Empty
is the empty relative paths, mostly used to mean "no path"FdbPath.Root
is the "/" absolute path, which is now the default location for most locations."/Foo[partition]/ACME/Users[SomeLayer]"
represents the path to a directory "Users" handled by 'SomeLayer', which is nested under the "Foo" partition.CreateAsync("/Foo/ACME/Users", "SomeLayer")
and end up with "Foo" being a regular directory and not a partition. Then, subsequent attempts to open Foo as a partition would fail (because now its layer id is empty instead of"partition"
).Slice
tostring
, which are encoded as utf-8 byte strings in the database./
,\
,[
and]
have to be escaped with a leading\
."/Foo/Bar/Baz"
) and just the directory name ("Foo"
) for APIs that take strings as argument.FdbPathSegment
struct that represents a segment, andFdbPath
is now a collection of these structs.This PR also fixes a few issues and bugs in the DL that were found while refactoring:
\xFE
byte appended to it.Renaming
FdbDirectoryPath
toFdbPath
is primary to reduce the length of the type, but also to force a code review of any use of that type in the application, to make sure that it is the correct type (absolute vs relative), and that it correctly includes any Layer Id.