jamescourtney / FlatSharp

Fast, idiomatic C# implementation of Flatbuffers
Apache License 2.0
497 stars 50 forks source link

Contextual Field Options #224

Closed jamescourtney closed 3 years ago

jamescourtney commented 3 years ago

Historically, FlatSharp has relied on the model that says: There is precisely one way to parse and serialize a given Type. This allows the generated code to be considerably simpler.

However, there are at least three instances in FlatSharp 5 and below of features beginning to stretch the limits of this model:

All of these would be simplified if a table could pass some context options to the serialize operation for those types when serializing/parsing. These options would need to be per-field, which could be challenging.

This would allow semantics such as the following:

table Foo
{
      MutableVector : [ int ] (fs_writeThrough, fs_preallocate:"Always");  // always preallocate. Possibly with writethrough
      ImmutableVector : [ int ] (fs_preallocate:"Never"); // never preallocate
      ImmutableVector : [ int ] (fs_preallocate:"Default"); // base decision about preallocation on the size of the vector and let Flatsharp decide at deserialization time.
}

This is a much richer semantic than a global setting that is applied for the whole serializer. Now there are 3 ways to parse [ string ]:

Such a change would mean (at least) the following:

jamescourtney commented 3 years ago

Some progress prototyping this to remove the SharedString class altogether.

Flatsharp can actually be really intelligent about it. Since we know the full object graph, we know if there are any shared strings or not in the graph. If there are not, we don't even need to include the if (IsSharedString) check when writing strings, so there doesn't need to be a performance penalty here. (though if you add a single shared string to the schema, then you're getting that if statement). The alternative is an explosion of methods for each combination of flags, which seems... not great.

The parameter can be omitted entirely if the target method doesn't need it.

This is starting to feel like the design that's needed to solve some of these problems and let FlatSharp evolve.