Add a fatal error condition for invalid Dictionary insertion distances

When choosing poor/aggressive values for `table_expire_interval`,
`table_expire_delay`, and/or `table_incremental_step` that tend to
leave tables in state of constant table-expiry-iteration, the underlying
Dictionary is never allowed the chance to complete remapping operations
which re-position entries to more ideal locations (e.g. after
reallocating the table to be able to store more entries).

That situation not only leads to the Dictionary generally having a less
efficient structure, but eventually, the lack of re-positioning may
cause an insertion to calculate the new entry's
distance-from-ideal-position to be a value requiring a full 16-bits or
more (>=65535), but an entry only allows storing 16-bit distance values,
with 65535 being a sentinel value that is supposed to indicate an empty
entry.  Dictionary operations may start misbehaving if that's allowed to
happen.
This commit is contained in:
Jon Siwek 2021-04-26 23:03:32 -07:00
parent d51bd4bc46
commit 292e3e18a3

View file

@ -1027,8 +1027,14 @@ int Dictionary::LookupIndex(const void* key, int key_size, detail::hash_t hash,
*insert_position = i;
if ( insert_distance )
{
*insert_distance = i - bucket;
if ( *insert_distance >= detail::TOO_FAR_TO_REACH )
reporter->FatalErrorWithCore("Dictionary (size %d) insertion distance too far: %d",
Length(), *insert_distance);
}
return -1;
}