Repository navigation
fix: preserve LRU overwrite recency across delayed reads - #283
Open
perfloop[bot] wants to merge 2 commits into
Open
perfloop[bot] wants to merge 2 commits into
perfloop[bot] wants to merge 2 commits into
Conversation
Signed-off-by: Perfloop Agent <agent@perfloop.ai>
Signed-off-by: Perfloop Agent <agent@perfloop.ai>
|
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.
The access updater no longer lets a delayed automatic read replace a later LRU timestamp published by an overwrite. This prevents the written key from moving ahead of older eviction candidates.
The guard applies only to admitted automatic updates in capped LRU.
Storage.GetandStorage.GetWithVersionshare the updater; FIFO and uncapped storage do not use it. The guard skips only when the current back-reference names the same key and its timestamp-derived bucket, signed nanosecond field, separators, and key are valid. Missing or malformed entries still follow the existing refresh path. Buffer-full drops, delay-gated reads, and same-key mutations between the flush lookup and commit remain outside the guarantee. ExplicitSetAccessTimecan still set an older timestamp. No public API, configuration, or index format changes.TestAccessUpdater_DelayedReadDoesNotUndoNewerOverwriteholds a successfulGetupdate until a successfulPutcommits in a later second, with an equal-sized key between the read and write times. It verifies both the t3 back-reference and the ordered row it names before ordinary LRU eviction. A same-batch later-index update confirms the access-update write committed. The test also checks that newer automatic reads advance recency and explicit olderSetAccessTimevalues remain possible.TestAccessUpdater_RewritesMalformedCurrentIndexverifies the old refresh behavior for malformed prefixes, buckets—including a valid bucket hour that disagrees with the timestamp—and separators. The frequency of this schedule in deployments remains unmeasured.make all,make test,make test-integration-cleaner,make test-integration TEST=TestIntegration_Objects/ObjectsSuite/Test_Objects_LRUEviction,make test-e2e-eviction,make lint,make license-check, storagego vet ./..., and the targeted storage race test passed. The full integration and E2E suites were not run.make test-integration-shortreached its configured 30-second package timeout on both revisions. The accepted-base run was intests/integration: TestIntegration_Objects/ObjectsSuite/Test_Objects_MixedSizes; the final run was intests/integration: TestIntegration_Objects/ObjectsSuite/Test_Objects_MixedTTL, during its two-second pre-read wait. These are suite-timeout locations, not test assertion failures. The Objects LRU eviction subtest had already run; its scoped regular integration check passed. The comparison runner is retained proof support and is not part of this pull request; the in-package regression and preservation tests ship.The test-only comparison at
5f4ed5ac3aed0c61d5f669cf1e3b70d57cfaea13reports violated for the asserted behavior.The final source reports satisfied for the same assertion.
Generated by Perfloop.
Note
Medium Risk
Changes LRU index flush semantics for capped storage; incorrect logic could skew eviction, but the guard is limited to automatic updates with validated index entries.
Overview
Fixes a race where a delayed automatic read (from
Get) could flush an older access timestamp and move a key ahead of a newer overwrite in the LRU index, causing wrong eviction under disk caps.Access updates from
UpdateNoware now tagged automatic. On flush, if the persisted bucketed access entry is well-formed and newer than the queued read time, the updater skips rewriting that key so overwrite recency is preserved. ExplicitUpdate/SetAccessTimepaths are unchanged.parseWellFormedBucketedAccessKeygates that comparison so malformed index rows still go through the normal refresh/delete path.Adds regression tests for read-after-overwrite ordering, eviction behavior, newer reads still advancing recency, and malformed index repair.
Reviewed by Cursor Bugbot for commit 8b49514. Bugbot is set up for automated code reviews on this repo. Configure here.