With the Record Layer, does the keyspace path get re-created when app re-starts?

A path has been defined at line 125: https://github.com/FoundationDB/fdb-record-layer/blob/master/examples/src/main/java/com/apple/foundationdb/record/sample/Main.java#L125.

Does this path get re-created each time the app re-starts?

I am not really an expert Java Developer, I am trying to use the record layer in my Clojure project through Java interop. My use-case is that I should be able to create path once, and get the path whenever I need via some method call on some class, because I am not sure of the effects of re-creating path each time I want to access it. I am not able to find any method on any class that can return the path if I supply path structure something like[dir-name sub-dir].

What would be a safe way to do this?


Hm, okay, I’m not entirely sure I understand the question fully, but I’ll try my best.

If the question is how expensive it is to create such a path in terms of database operations, I’ve tried to answer that question below.

The KeySpacePath abstraction allows you to map logical structure to physical structure, which is especially useful if you have multiple record stores that you are trying to manage. In the sample app, for example, you could have multiple applications with multiple “environments” (e.g., “prod” or “qa”). The other neat thing is that you can assign your meaningful names (e.g., “prod”) shorter values (e.g., the integer 0) which are more space efficient, and then when paths are logged, the key space path will fill in the logical name for you so you can make sense of the path given.

None of that necessarily requires doing any I/O, so all of that is fairly cheap to do and fairly cheap to recreate every time you create a new record store. So, if the concern is that “creating” the path will require a bunch of work, that generally shouldn’t be a problem. The one exception to that is the “directory layer directory”, which uses FDB’s directory layer to turn your string into an integer. For that, the Record Layer keeps a cache in the FDBDatabase mapping directory layer entries to their resolved integers, so the first time you use a path, you will need to read from the database, but if you only have a limited number of these, then you won’t need to read from the DB again.

But other than the directory layer mapping of string to integer (which is persisted in the DB), there isn’t actually a durable log of the path in the database, so creating the path object only should cost a small amount of memory and CPU. You can still list paths, but that requires doing a kind of “smart scan” of the database that does a series of small scans to figure out what the values of the path are.

If the concern is that every time you create a record store you need to also create the path, you can do a few things. One is keep the path object around in your own configuration class (that you then call a “create record store” method on that fills in the key space path in a record store), and another is use an FDBRecordStore.Builder as a kind of “record store factory”, and then you can call builder.copyBuilder().setContext(context).open() to open the same store in multiple places.

It’s also possible I’ve misunderstood your use case, which sorry for that if that’s the case.

Also note from the comment in the sample and @alloc’s reply that using key space paths means defining a structure for the hierarchy of record stores in the database. That is the KeySpace from which KeySpacePaths are built.

If on the other hand you want a raw specification of the hierarchy, you could use .setSubspace on the builder instead of .setKeySpacePath. Then something like

(com.apple.foundationdb.subspace.Subspace. (com.apple.foundationdb.tuple.Tuple/from (into-array [dir-name sub-dir])))

would construct that variable part. This isn’t as compact, because it does not turn strings into integers, but it’s less conceptual overhead for getting started. (Or you could use the directory layer for the root and build a subspace beneath it.)

Thanks @alloc and @MMcM for detailed explanation. Helps a lot. I think I misunderstood the path creation part. I thought that it was doing an I/O with the FDB and was setting some structure in the DB,
and next time when I create that path again, it will again do an I/O and do some overriding in the DB.
But, I now see that this path creation is just a function operation that returns a path - no communication with DB yet.
This confusion has to do with my limited understanding of Java - sorry about this.
Please do correct if I am wrong in my understanding.

Thanks much!