diff --git a/util/deephash/deephash.go b/util/deephash/deephash.go index 6112c6ff2..b6a9bc40b 100644 --- a/util/deephash/deephash.go +++ b/util/deephash/deephash.go @@ -106,9 +106,20 @@ func (s1 *Sum) xor(s2 Sum) { } func (s Sum) String() string { + // Note: if we change this, keep in sync with AppendTo return hex.EncodeToString(s.sum[:]) } +// AppendTo appends the string encoding of this sum (as returned by the String +// method) to the provided byte slice and returns the extended buffer. +func (s Sum) AppendTo(b []byte) []byte { + // TODO: switch to upstream implementation if accepted: + // https://github.com/golang/go/issues/53693 + var lb [len(s.sum) * 2]byte + hex.Encode(lb[:], s.sum[:]) + return append(b, lb[:]...) +} + var ( seedOnce sync.Once seed uint64 diff --git a/util/deephash/deephash_test.go b/util/deephash/deephash_test.go index 303327f75..5869fe7fa 100644 --- a/util/deephash/deephash_test.go +++ b/util/deephash/deephash_test.go @@ -1050,3 +1050,25 @@ func FuzzAddr(f *testing.F) { } }) } + +func TestAppendTo(t *testing.T) { + v := getVal() + h := Hash(v) + sum := h.AppendTo(nil) + + if s := h.String(); s != string(sum) { + t.Errorf("hash sum mismatch; h.String()=%q h.AppendTo()=%q", s, string(sum)) + } +} + +func BenchmarkAppendTo(b *testing.B) { + b.ReportAllocs() + v := getVal() + h := Hash(v) + + hashBuf := make([]byte, 0, 100) + b.ResetTimer() + for i := 0; i < b.N; i++ { + hashBuf = h.AppendTo(hashBuf[:0]) + } +}