-
Notifications
You must be signed in to change notification settings - Fork 255
perf: reduce allocations through memoization #3219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c8d0622
1070f7c
78b6ff6
52a684e
192b483
8d2fef6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,27 +41,65 @@ func (h *Header) HashLegacy() (Hash, error) { | |
| return hash[:], nil | ||
| } | ||
|
|
||
| // Hash returns hash of the header | ||
| // Hash returns the header hash. It reuses a memoized value if one has already | ||
| // been prepared via MemoizeHash, but it does not write to the header itself. | ||
| func (h *Header) Hash() Hash { | ||
| if h == nil { | ||
| return nil | ||
| } | ||
| if h.cachedHash != nil { | ||
| return h.cachedHash | ||
| } | ||
|
|
||
| slimHash, err := h.HashSlim() | ||
| if err != nil { | ||
| return h.computeHash() | ||
| } | ||
|
|
||
| // MemoizeHash computes the header hash and stores it on the header for future | ||
| // Hash() calls. Call this before publishing the header to shared goroutines or | ||
| // caches. | ||
| // | ||
| // If a Header struct is reused (e.g. overwritten via FromProto or field | ||
| // assignment), call InvalidateHash() first to clear the cached value before | ||
| // calling MemoizeHash again. Failure to do so will return the stale cached hash. | ||
| func (h *Header) MemoizeHash() Hash { | ||
| if h == nil { | ||
| return nil | ||
| } | ||
| if h.cachedHash != nil { | ||
| return h.cachedHash | ||
| } | ||
|
|
||
| hash := h.computeHash() | ||
| if hash != nil { | ||
| h.cachedHash = hash | ||
| } | ||
| return hash | ||
| } | ||
|
Comment on lines
+44
to
+77
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Synchronize Lines 50-51, 64-70, and 91-93 access Also applies to: 89-95 🤖 Prompt for AI Agents |
||
|
|
||
| func (h *Header) computeHash() Hash { | ||
| // Legacy hash takes precedence when legacy fields are present (backwards | ||
| // compatibility). Slim hash is the canonical hash for all other headers. | ||
| if h.Legacy != nil && !h.Legacy.IsZero() { | ||
| legacyHash, err := h.HashLegacy() | ||
| if err == nil { | ||
| if legacyHash, err := h.HashLegacy(); err == nil { | ||
| return legacyHash | ||
| } | ||
| } | ||
|
|
||
| slimHash, err := h.HashSlim() | ||
| if err != nil { | ||
| return nil | ||
| } | ||
| return slimHash | ||
| } | ||
|
|
||
| // InvalidateHash clears the memoized hash, forcing recomputation on the next | ||
| // Hash() call. Must be called after any mutation of Header fields. | ||
| func (h *Header) InvalidateHash() { | ||
| if h != nil { | ||
| h.cachedHash = nil | ||
| } | ||
| } | ||
|
|
||
| // Hash returns hash of the Data | ||
| func (d *Data) Hash() Hash { | ||
| // Ignoring the marshal error for now to satisfy the go-header interface | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.