Yeah, that’s right: you do have to use a
DirectoryLayerDirectory to get the key space to use the directory layer. A regular
KeySpaceDirectory will just insert the string directly into the key. Sorry for the confusion.
The Record Layer doesn’t use any (set) top level directory for its data. It’s entirely up to the user and determined wholly by the
KeySpacePath provided. So, for example, you may choose to create a root key space directory node that looks like:
KeySpace keySpace = new KeySpace(new DirectoryLayerDirectory("root", "myApplicationName"));
KeySpacePath rootPath = keySpace.path("root");
In this case, “root” is the name of the root key space directory, and its value will always be the integer that “myApplicationName” resolves to in the FDB directory layer. If you create any record store in that path or in any subpath of that path, it will be constructed in a subspace that also begins with that integer (encoded to bytes using the FDB tuple layer). If you were to then call
fdb.directory.list(db), you should find an entry for
myApplicationName, and in the associated FDB subspace, you’d find all of the data that is stored under that root path.
But you could also imagine a slightly more complicated structure. Something like:
KeySpace keySpace = new KeySpace(new DirectoryLayerDirectory("root", "myApplicationName")
String userId = getUserId();
KeySpacePath userPath = keySpace.path("root").path("user", userId);
In this case, the
userPath begins with the same integer from before, but the next element in the tuple will be the user’s ID, turned into an integer using the directory layer. So, now if you call
fdb.directory.list(db), you’d find both “myApplicationName” as well as all user IDs, and if you tried to use the directory layer to open any individual ID, you’d find that it’s empty, even if you’ve created record stores with the above key space path.
One further note: the
recdb_rd_cache is used to store data for the “reverse directory layer”, i.e., a data structure to turn directory layer values back into strings. This is used by the “list” methods on key spaces, which operate by reading raw keys from the database, and then translating their individual elements back into their original values. The directory layer doesn’t (efficiently) support this natively, so that’s why an additional directory was needed.
Things are a bit simpler if you use the
ScopedInterningLayer instead, which has forward and reverse mappings built in. However, it uses a separate place to store data from the FDB directory layer, so, for example, if you have two applications on the same FDB cluster, one of which uses the
ScopedInterningLayer to allocate a subspace and other of which uses the FDB directory layer, then they might end up writing data to the same prefix (even if they coördinate on using separate root directory names).