fix(utils): update existing keys in-place in FifoCache::push#2065
Open
amathxbt wants to merge 2 commits into0xMiden:nextfrom
Open
fix(utils): update existing keys in-place in FifoCache::push#2065amathxbt wants to merge 2 commits into0xMiden:nextfrom
amathxbt wants to merge 2 commits into0xMiden:nextfrom
Conversation
When push() was called with an already-present key the previous implementation unconditionally appended the key to the eviction queue before calling map.insert(). This created a ghost entry: the eviction queue length exceeded the number of live map entries, effectively reducing unique-entry capacity and causing a valid value to be prematurely dropped when the ghost surfaced as the oldest key. Fix: check map.contains_key() first and, when the key exists, update the value in-place without touching the eviction queue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FifoCache::pushunconditionally appendedkeyto the eviction queue before callingmap.insert, even when the key was already present in the cache. This created a ghost eviction entry: the queue length grew beyond the number of live map entries, consuming an eviction slot that had no corresponding map value. When that ghost eventually surfaced as the oldest entry,map.removefound nothing—silently discarding the slot—while the queue shrank by one. The net effect was that the cache's effective unique-entry capacity was reduced by one for every overwrite, and a still-live entry could be prematurely evicted.Root Cause
With
capacity = 2:push(A, 1)→ queue:[A], map:{A:1}push(A, 2)→ queue:[A, A], map:{A:2}← ghost created, capacity consumedpush(B, 3)→ evicts oldestA(ghost); queue:[A, B], map:{A:2, B:3}← fullpush(C, 4)→ evicts realA; queue:[B, C], map:{B:3, C:4}← A lost prematurelyFix
Check
map.contains_key(&key)first. When the key exists, update the value in-place and return immediately, leaving the eviction queue unchanged:Testing
Added two new tests:
overwrite_key_updates_value_in_place— verifies that overwriting a key does not consume an extra eviction slot.overwrite_does_not_change_eviction_position— verifies that the overwritten key is still evicted at its original FIFO position when the cache later fills up.CHANGELOG
Added entry to
## v0.15.0 (TBD)section.