tidwall / btree

B-tree implementation for Go
MIT License
1.06k stars 83 forks source link

question about crash during iteration (probably because of mutation during iteration) #39

Open sahib opened 11 months ago

sahib commented 11 months ago

Hello @tidwall,

thank you a lot for this very nice module, it was very handy to me several times.

I'm trying to debug a crash in one of my applications:

runtime error: index out of range [44] with length 31 - trace:

/usr/lib/go/src/runtime/panic.go:914 +0x244
github.com/tidwall/btree.(*MapIter[...]).Next(0x1488618)
    .../github.com/tidwall/btree@v1.7.0/map.go:1051 +0x258
github.com/sahib/timeq/index.(*Iter).Next(0x3993ca0)
    .../github.com/sahib/timeq@v0.0.0-20231205120808-c044c518c189/index/index.go:152 +0x7c

The respective program has roughly the following structure and is single-threaded (so we can rule out data races):

var m *btree.Map[string,string]
for m := m.Iter(); iter.Next(); {   // crash in Next() sometimes
    // ...
    if someCondition {
        m.Set("foo", "bar")
    }
   // ...
}

If I'm reading the code for map iteration right, then mutation during iteration does not seem to be supported as Set() does not seem to update the current iterators' stack. Is this correct and is this missing from the documentation? If yes, adding it would be great. I could do a PR if you want.

sahib commented 11 months ago

I just realized the doc string for Iter() says Iter() returns a read-only iterator. I somehow missed that. Well, I guess this can be closed then.

tidwall commented 11 months ago

Optionally you can copy the btree before iterating using the Copy function. This will allow for mutating the original btree while iterating over the copy.