Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SortedMultiDict losing elements #773

Closed
dantaras opened this issue Nov 17, 2021 · 5 comments
Closed

SortedMultiDict losing elements #773

dantaras opened this issue Nov 17, 2021 · 5 comments
Labels

Comments

@dantaras
Copy link
Contributor

s = SortedMultiDict{Int, Int}()           
insert!(s, 4, 41)
insert!(s, 3, 31)
insert!(s, 2, 21)
insert!(s, 2, 22)
insert!(s, 2, 23)
insert!(s, 2, 24)
insert!(s, 2, 25)
insert!(s, 2, 26)
insert!(s, 1, 11)
insert!(s, 1, 12)

st1 = insert!(s, 1, 13)
st2 = insert!(s, 1, 14)
st3 = insert!(s, 1, 15)
st4 = insert!(s, 1, 16)
st5 = insert!(s, 1, 17)
st6 = insert!(s, 1, 18)

delete!((s, st6))
delete!((s, st5))
delete!((s, st4))
delete!((s, st3))
delete!((s, st2))
delete!((s, st1))

@show s
insert!(s, 1, 19)
@show s

count = sum(1 for _ in s)
@assert count == length(s) "$count $(length(s))"

Running the above I get an assertion error:

ERROR: LoadError: AssertionError: 6 11

Some of the items in the SortedMultiDict are lost after the last insert.

@StephenVavasis
Copy link
Contributor

Thanks for reporting this; I have confirmed the issue and am looking into it.

@oxinabox oxinabox added the bug label Nov 17, 2021
@StephenVavasis
Copy link
Contributor

StephenVavasis commented Nov 17, 2021

I have created a pull request that fixes the bug. It would be great if the OP could also test the new code on their actual application. The fix is in a branch called fix_sortedmultidict_bug

#775

Here is the explanation of the bug. In order to insert a data item as a leaf in a balanced 2-3 tree, it is necessary to adjust ancestors of the leaf by splitting ancestor nodes and reconnecting them to children. When I originally wrote the balanced tree substrate in 2013, for some inexplicable reason, I wrote insert! code that reconnects ancestors to children via comparison of keys rather than simply extending existing parent-child relations. Unfortunately, I missed an edge-case in the key comparisons, so that the previous code occasionally (and only for SortedMultiDict, not for the other two containers) reconnected ancestor nodes incorrectly. The new version of insert! navigates and reconnects ancestors without any key comparisons. So the new code for insert! is shorter, faster, and hopefully bug-free.

@dantaras
Copy link
Contributor Author

I can confirm that the fix works. Thanks for the quick response!

StephenVavasis added a commit to StephenVavasis/DataStructures.jl that referenced this issue Nov 18, 2021
StephenVavasis added a commit that referenced this issue Dec 7, 2021
#775)

* Fixed long-standing bug in balanced_tree.jl that corrupted SortedMultiDict
for certain insertions.

* Added test case from issue #773
oxinabox pushed a commit that referenced this issue Dec 8, 2021
#775)

* Fixed long-standing bug in balanced_tree.jl that corrupted SortedMultiDict
for certain insertions.

* Added test case from issue #773
@StephenVavasis
Copy link
Contributor

I guess we can close this issue with the new release of 0.18.11. Should I make an announcement on discourse.julialang.org? I'm not sure how many users of SortedMultiDict are out there.

@oxinabox
Copy link
Member

I do not think it needs an announcement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants