FoundationDB / fdb-record-layer

A record-oriented store built on FoundationDB
Apache License 2.0
588 stars 102 forks source link

Meta-data templates / parameterized meta-data #315

Open MMcM opened 5 years ago

MMcM commented 5 years ago

Capturing two comments from a closed pull request:

@nschiefer https://github.com/FoundationDB/fdb-record-layer/pull/198#issuecomment-451213320

I think this suggests that we've merged two distinct concepts so far. From the perspective of most Record Layer tasks, like index maintenance, what really matters is some concrete instantiation of the metadata, specialized to include the values of parameters like locale. However, a developer really wants to provide a higher-level metadata template with parameters that can be slotted in by store-specific info. Perhaps it makes sense to make this distinction clear at the API level? That would be a lot of work, though.

@alecgrieser https://github.com/FoundationDB/fdb-record-layer/pull/198#issuecomment-451246090

I suppose you could make the idea of a "meta-data template" more concrete. One way this might go would be something like:

  • Introduce a ParameterizedRecordMetaData type. This is the "meta-data template". It might need a toProto method that returns a MetaData proto.
  • Introduce a ParameterizedKeyExpression type. These can be bound or unbound; unbound key expressions are legal in ParameterizedRecordMetaData objects but not in RecordMetaData objects. (It would also be sufficient to allow unbound parameters in RecordMetaData objects that are never given to record stores.)
  • A BoundParameterizedRecordMetaData is then a ParameterizedRecordMetaData plus a parameter map. It is also a RecordMetaDataProvider', and it'sgetRecordMetaData` method only ever returns bound key expressions.
  • Calling toProto() on ParameterizedKeyExpressions only serializes the parameter names, not their values, even if the parameter is bound, so the serialized meta-data doesn't contain them (or maybe something slightly more sophisticated, but it needs to sometimes serialize unbound key expressions which is what a user puts in the MetaDataStore, for example).

I think in this scheme, the KeyExpression, when it's actually called, knows everything that it needs to generate the index expression, but the parameter map does need to be somehow communicated to the ParameterizedRecordMetaData to make a valid RecordMetaData.

The only difference from having the user roll their own "generate my meta-data for this store" method is that (I think) the problem of serializing and storing the meta-data is now something the Record Layer takes on (or, like, the fact that one is using something of a wonky meta-data is more explicit). I'm not entirely sure I see if it would be better than having an "index building context" object that gets passed to key expressions at evaluation time more directly.

MMcM commented 5 years ago

I think maybe ParameterizedRecordMetaData can just be RecordMetaDataBuilder, meaning that you have to bind the parameters before getRecordMetaData will succeed.

Impliying #316.

There could be a way for FDBRecordStore.Builder to supply parameter bindings to its RecordMetaDataBuilder RecordMetaDataProvider. In particular, it could load them from the partially-open store subspace.

Implying an isParameterized extension to #282.

alecgrieser commented 5 years ago

One concern I would have with using a RecordMetaDataBuilder as the parameterized thing would be that you couldn't share the object between different threads talking to different record stores (or you'd have to be really careful not to accidentally pollute the parameters of one store with the parameters of another).