Skip to content

pass a real rehash hasher to MapHashTable reserve / shrink#235

Merged
sunshowers merged 2 commits intomainfrom
sunshowers/spr/pass-a-real-rehash-hasher-to-maphashtable-reserve-shrink
Apr 23, 2026
Merged

pass a real rehash hasher to MapHashTable reserve / shrink#235
sunshowers merged 2 commits intomainfrom
sunshowers/spr/pass-a-real-rehash-hasher-to-maphashtable-reserve-shrink

Conversation

@sunshowers
Copy link
Copy Markdown
Collaborator

@sunshowers sunshowers commented Apr 22, 2026

Previously, MapHashTable::reserve, try_reserve, shrink_to_fit, and shrink_to all
delegated to hashbrown::HashTable with |_| 0 as the rehash hasher.
When the capacity change triggers a reallocation, hashbrown's rehash
pipeline (resize_inner / reserve_rehash_inner) calls the supplied hasher
for every surviving entry and uses the result to pick its new bucket.
Returning 0 for every key crowds all entries into bucket 0 of the new
table; subsequent lookups probe from hash(key) mod capacity and miss,
so the map silently appears empty to get/find_index while iteration
still returns every item.

Also, reserve and try_reserve are reachable through the public API of
IdHashMap / BiHashMap / TriHashMap, including via Extend, which
pre-reserves size_hint / 2 before inserting.

The fix is to take a real hasher at the MapHashTable layer and plumb |ix| state.hash_one(items[*ix].keyN()) through every caller.

Also add coverage for these methods to our proptests.

Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
@sunshowers sunshowers merged commit d5500c8 into main Apr 23, 2026
33 checks passed
@sunshowers sunshowers deleted the sunshowers/spr/pass-a-real-rehash-hasher-to-maphashtable-reserve-shrink branch April 23, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant