Replies: 2 comments 2 replies
|
It seems the simpler is better path solves this -- if I don't try to do this whole thing recursively, but instead focus on just one layer - i.e. columns, it makes the whole thing much easier. In other words, there will be only one type for a |
|
huh, TIL about the This smells like a similar set of decisions that I faced when designing the data model for Valinor, where we want to have zero-copy loading of data in pointers. The main difference is that it sounds like you're needing to actually decode data. Specifically, we mostly cared about mapping into a structure using For cases where we want to read data out, we do this lazily. It can be thought of as similar to decoding actually, except that in your case it sounds like you always want to decode the whole column (I think you got that right in your follow-up comment!).
This is exactly what we needed to do as well with Valinor. Basically we want to be able to interpret some bytes in memory as a tile, but don't actually copy anything unless we need to modify it. We used the standard library You can find the full code for the builder here: https://github.com/stadiamaps/valinor/blob/main/valhalla-graphtile/src/graph_tile/builder.rs. TL;DR it sounds like you've probably found good enough modeling principles for a first pass. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I keep thinking how to best organize Rust data model. Data can be in multiple states:
struct RawFoo<'a>struct OwnedFoostruct DecodedFooThe expected usage patterns are:
Current Code Structure
Given the raw input bytes, the parser quickly runs over the input slice and only stores references to the streams and their metadata. Later, decoding can be done on-demand, either for all columns, or just for the specific ones. This example is for
Id, but the same idea applies toGeometry,Property,v01::Layer, and rootLayerentities.RawIdstruct contains references into the original input data. The values are not decoded, just some metadata is parsed. Most data is stored asStream<'a>instances, which hold references to parts of the original input and tie to input lifetime.OwnedRawIdstruct is auto-generated with the borrowme crate - it has the same fields as theRawIdstruct, but owns its data. This is useful when you want to store aRawIdstruct beyond the lifetime of the original input slice, or when you want to modify it or store the result of the encoding before storing it into a file.DecodedIdstruct is used to store the decoded value. At the moment, onlyDecodedGeometryis implemented, but the same idea applies to other entities. The decoded values are stored in standard Rust types, e.g.Vec<u64>for IDs.Idenum containsRaw(RawId)andDecoded(DecodedId)variants, with values described above. This allowsin-placedecoding, e.g. it is possible to decode just one property column / ID / Geometry, while keeping the rest in their raw form. The enum also has a correspondingborrowme-generatedOwnedId.All reactions