Repository navigation
Conversation
Meets and joins keep the left operand's value on a collision. A list node joining a byte node merged itself into a copy of the byte node, and a byte node meeting a list node let the list node run the meet, so either way the list node's values won wherever it was. The join now goes through a byte-node copy of the list node, and the meet tells the list node it is the right operand. merge_guts also joined a list node's payload with the other slot's child on the right.
Finding 4 of the algebraic fuzzer: with b a clone of a plus one value, a.join(&b) dropped that value while b.join(&a) kept it. Fixed by the value-bias change to which operand a byte-node/list-node join keeps.
When a list node holds a value and a child under the same key and the child meets an empty node, the meet left an empty child (a dangling sentinel) next to the value, which validate_node rejects. The value already keeps the path, so drop the sentinel. Reachable once the value-bias fix put the empty node on the left of the child meet: EmptyNode's meet keeps a dangling tip, while the other order returned None.
Owner
|
Algebraic ops should assume lattice values. Keeping the left operand is not, hence the behavior is undefined/op is unsupported. |
Owner
|
Please add the join fix separately to #178 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
On a collision,
joinandmeetkeep the left operand's value (pjoin/pmeetonu64returnself). Which value survived actually depended on how each operand happened to be stored: when one side was a list node andthe other a byte node, the list node's value won whichever side it was on.
The same held for
meet,meet_2,meet_intoandjoin_intowherever a byte node meets a list node.Changes
Make meet and join value bias independent of node layout
left. This removes the old merge-into-a-copy arms and
CellByteNode::clone_as_dense, which nothing else used.swappedflag throughpmeet_genericnow makes it resolve each collision asother op self. Converting to a byte node doesn't work here: a byte-to-byte meet drops dangling paths, andmap_meet_dangling_branching_factor_test1requires them in both operand orders.merge_guts: when one list node's payload is joined with the other's child, the payload now goes on the left.Test that a join keeps a value across clone-shared structure
With
b = a.clone()plus one value,a.join(&b)dropped that value andb.join(&a)kept it. The fix above resolves this; the test fails on master.Drop an emptied child beside a value in a list-node meet
Once the meet runs with the operands the right way round, a list node holding a value and a child under the same key can meet the child down to an empty node. The result kept that empty child next to the value, which is an
invalid node and trips a debug assertion. The empty child is now dropped, because the value already keeps the path.
Testing
meet_value_bias_is_left_regardless_of_node_layout:meet_2andmeet_intoacross list, byte and tiny layouts.join_value_bias_is_left_regardless_of_node_layout:joinandjoin_into, at the root and one level down.map_join_keeps_value_across_shared_structuremap_meet_value_beside_emptied_child: catches the invalid node in debug builds.u64value-bias findings. They came from routes that disagreed withPathMap::join/PathMap::meet:model,dnf,nary,ternary,subtract_zipper, and thezipper_join/OverlayZipperjoin strategies. The join value-loss cases also drop by more than half.Not included
join_k_path_intostill folds k-paths in its current order, so on a collision the value that survives may not come from the first path. That is a separate question about what the spec should say.differences on the
join_into_takestrategy, never in values.