-
Can the number of bytes used in a builder object be estimated/returned before the buffer is ended or closed out? For example, let's say I have a simple table:
Over time I want to append data to both data_1 and data_2. My C code might start with:
And then I call this from time to time where I am appending new data onto one (or both) of my table array fields.
or
I know that when I "end" the data_1 field I can call "flatcc_builder_get_buffer_size() to get the size of the final serialized buffer. So far so good. IE:
However, without counting bytes myself (which is my fallback plan), can I get an estimate of how many bytes will be consumed BEFORE I call:
I tried calling "flatcc_builder_get_buffer_size()" prior to ending and it returns 0. And actually, one additional related side question. Is it possible to "start" two separate table fields, append to them both over time, and then "end" them both sometime later? Or does the builder require us to close out one table field before starting another? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
To your last side question first. Unlike other languages, flatcc allows for having multiple tables open at once, however, they must be nested. You cannot have an arbitrary number of unrelated tables open at once. This is because all unclosed tables share the same stack. The stack leads to your first question: Get buffer size should be valid before the end of the entire buffer, but maybe not that exact function call you refer to - there is an end and start method (or something to that effect - look at the source) used extensively internally. These are the virtual start and end offset that grow up and down and eventally extends to the entire buffer and defines the buffer size. But these only grow when data is emitted: Flatcc builds buffers in two stages: on the stack via the builder object, and in the emitter that maintains final buffer data (even if not physically assembled into a single buffer yet, it maintains a virtual address space that precisely reflects the buffer size so far). So, for things not yet emitted, you do not get the size data that you are seeking. Things are generally emitted when ended as you have come to suspect. The build stage is sometimes skipped if the input data can be directly emitted, such as a native little endian integer array, or a string, but conceptually data flows the same way - it is just an optimization - you are still ending something. So, if you want more insight, you need to watch the stack space. This is not trivial because there are about 7 or different kinds of stacks for different purposes, but the ds stack is the most relevant. All stacks use their current active size as stack pointer because it is robust to reallocation. You find the stack pointers in struct inside the builder, as I recall. While unlikely to change, direct access to these data is undocumented and subject to change. You want to be particularly careful with nested buffers, notably not dragging references across boundaries, but by and large nested buffers work as child objects same as always, only alignment is really tricky to get right for the builder. Hence size estimates shouldn't be much different. |
Beta Was this translation helpful? Give feedback.
-
Something somewhat different that might have your interest in this context: you can build several buffers concurrently as long as you use separate builder objects. When a buffer is completed, you can use it to clone data into another buffer. While this is extra data copying, it should still be fairly efficient if not abused. You can use this to collect long running data via append that eventually needs to land in another buffer, but you cannot keep appending in a single buffer due to the constraints mentioned. You can cache data in your own memory, or use FlatBuffer to do that management in a separate buffer. |
Beta Was this translation helpful? Give feedback.
-
Also, I could be more specific in my previous answer, but I don't recall all the details up front. builder.h is reasonably commented and should be a good starting point. |
Beta Was this translation helpful? Give feedback.
To your last side question first. Unlike other languages, flatcc allows for having multiple tables open at once, however, they must be nested. You cannot have an arbitrary number of unrelated tables open at once. This is because all unclosed tables share the same stack.
The stack leads to your first question:
Get buffer size should be valid before the end of the entire buffer, but maybe not that exact function call you refer to - there is an end and start method (or something to that effect - look at the source) used extensively internally. These are the virtual start and end offset that grow up and down and eventally extends to the entire buffer and defines the buffer size. But these onl…