mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Fix assertions in dictionary that can trigger for benign reasons.
These assertions were checking for a situation that I believe can happen legitimately: a robust iterator pointing to an index that, after some table resizing, happens to be inside the overflow area and hence empty. We'll now move it to the end of the table in the case.
This commit is contained in:
parent
b4f52ff311
commit
6491db6617
1 changed files with 14 additions and 1 deletions
15
src/Dict.cc
15
src/Dict.cc
|
@ -1832,7 +1832,20 @@ detail::DictEntry Dictionary::GetNextRobustIteration(RobustDictIterator* iter)
|
|||
if ( iter->next < 0 )
|
||||
iter->next = Next(-1);
|
||||
|
||||
ASSERT(iter->next >= Capacity() || ! table[iter->next].Empty());
|
||||
if ( iter->next < Capacity() && table[iter->next].Empty() )
|
||||
{
|
||||
// [Robin] I believe this means that the table has resized in a way
|
||||
// that we're now inside the overflow area where elements are empty,
|
||||
// because elsewhere empty slots aren't allowed. Assuming that's right,
|
||||
// then it means we'll always be at the end of the table now and could
|
||||
// also just set `next` to capacity. However, just to be sure, we
|
||||
// instead reuse logic from below to move forward "to a valid position"
|
||||
// and then double check, through an assertion in debug mode, that it's
|
||||
// actually the end. If this ever triggered, the above assumption would
|
||||
// be wrong (but the Next() call would probably still be right).
|
||||
iter->next = Next(iter->next);
|
||||
ASSERT(iter->next == Capacity());
|
||||
}
|
||||
|
||||
// Filter out visited keys.
|
||||
int capacity = Capacity();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue