Skip to content

fix(aich): self-heal LoadHashSet offset cache on successful rewind - #193

Merged
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/aich-loadhashset-self-heal-cache
Jun 17, 2026
Merged

fix(aich): self-heal LoadHashSet offset cache on successful rewind#193
got3nks merged 1 commit into
amule-org:masterfrom
got3nks:fix/aich-loadhashset-self-heal-cache

Conversation

@got3nks

@got3nks got3nks commented Jun 17, 2026

Copy link
Copy Markdown

Summary

Follow-up to #191.

#191 added a defensive rewind so LoadHashSet finds the right entry even when the cached offset is stale (known2.met modified externally between cache load and the request). The rewind worked, but it didn't update the cache after recovering — so every subsequent LoadHashSet for the same stale root hash kept paying the seek-miss + full linear scan instead of the O(1) cache hit the cache exists to provide.

The cache only self-cleared on daemon restart, on CEOFException-driven truncation, or after an orphan-prune rewrite in CAICHSyncTask::Entry() — none of which fire just because a single entry's offset went stale.

What this changes

In the match handler inside LoadHashSet:

  • Capture the entry's start position pre-read (entryStartPos) so we know the exact offset of the root hash — matching the value LoadRootHashCacheLocked and SaveHashSet write into the cache.
  • When the match happens AND we got there via the stale-cache rewind (cacheFallbackTriggered == true), stamp the new offset back into s_rootHashCache. Future lookups for the same hash go straight to the right offset.

Total diff is 12 lines added.

Verification

  • Local Mac build clean.
  • CI for the other targets.

The fast-path (cache fresh, first read matches) is unchanged: cacheFallbackTriggered stays false, so the cache-update branch is skipped. Self-heal cost is one mutex lock + one map write, only on the rewind path, only on successful recovery.

PR amule-project#191 added a defensive rewind so LoadHashSet finds the right entry
even when the cached offset is stale (known2.met modified externally
between cache load and the request). The rewind worked but didn't
update the cache: every subsequent LoadHashSet for the same stale
root hash kept paying the seek-miss + full linear scan, instead of
the O(1) cache hit the cache exists to provide. The cache only
self-cleared on daemon restart, on CEOFException-driven truncation,
or after an orphan-prune rewrite in CAICHSyncTask -- none of which
fire just because a single entry's offset went stale.

When the rewind succeeds, the linear scan has just found the right
position for the root hash. Stamp it back into s_rootHashCache so
future lookups for the same hash go straight there.

Capture the entry's start position pre-read (entryStartPos) so we
have the exact offset of the root hash, matching the value
LoadRootHashCacheLocked and SaveHashSet write into the cache.
@got3nks
got3nks merged commit e79c457 into amule-org:master Jun 17, 2026
10 checks passed
@got3nks
got3nks deleted the fix/aich-loadhashset-self-heal-cache branch June 17, 2026 14:00
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