Decoder: disallow modification of existing table #704
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #703. The idea is to mark tables created by key/values as explicit when entering the following table so that they can only be redefined within the same "block", not after.
This also makes two changes to the way used to track previously seen TOML objects to make up for the performance hit created by the extra marking.
First, introduce a dedicated tracker for inline tables. Because inline tables are self contained and cannot redefine anything outside of their scope, having their own tracker allows for very fast clean up (just forget about the object). To avoid allocating memory for every single inline table, a
sync.Pool
is used to salvage previous allocations.Second, and more importantly: the tracking structure is now an array-backed intrusive linked list. Nodes are fully addressed using their index in the array (as opposed to the mix of ID and index). Every node points to its first child and sibling (if any). This allows operations to just consider relevant nodes, as opposed to always do range scans on the array. To make index manipulation easier (remove a lot of
if idx >= 0
), the structure now always contains at least one element: the root table. It is special because its siblings are used as a free list of entries. This allows reusing existing memory (less allocations), and avoids the former operation of literally moving data around to keep the array compact -- or to maintain a separate structure just for the free list.The benchmark for
SimpleDocument
(literallyA = "hello"
) is slower, as the initial setup has more overhead. It is still quite fast, so probably no need to optimize that case further.