mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 09:45:24 +02:00
DenseHashMap and PrehashMap are the open-addressed, linear-probing maps behind the texture cache, the shader managers and the software renderer's sampler/drawpixel caches, and had no coverage. Writing the tests turned up a latent hang. Removal leaves tombstones, which occupy probe slots exactly like live entries, but the load factor check only looked at count_. So a workload that inserts and removes distinct keys keeps count_ low forever while REMOVED fills the table, and no Grow is ever triggered. Once there is no FREE bucket left, a lookup for a missing key has nothing to terminate on - and the probe loops don't break out after their "Hit full" assert, which is compiled out in release builds. The test reproduced it as a hard hang in about a second. Two fixes: count tombstones towards the load factor (rebuilding in place when the load is mostly tombstones, growing otherwise), and make the probe loops return instead of spinning if they ever do wrap all the way around. Not reachable today - nothing in GPU/ calls Remove() on these maps, and Maintain(), which exists to rebuild when tombstones pile up, is never called anywhere. But Remove() is public API and the first caller to use it in a loop would have hit an unexplained freeze. Tests cover insert/get/miss/remove/size, tombstones not cutting a probe chain, Iterate visiting exactly the live entries, Clear, growth past the initial capacity, Rebuild compacting, a 20000-operation differential test against std::unordered_map, and the tombstone churn above. PrehashMap gets the same treatment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9