Merge pull request #1 from ucan-wg/constants-alloc

perf(constants): avoid allocating a map for each Decode*() call
This commit is contained in:
Steve Moyer
2025-07-08 11:53:19 -04:00
committed by GitHub
2 changed files with 40 additions and 27 deletions

View File

@@ -12,7 +12,7 @@ import (
const Prefix = uint64(multicodec.Varsig)
// HashAlgorithm is the multicodec.Code that specifies the hash algorithm
// that's used to reduced the signed content
// that's used to reduce the signed content
type HashAlgorithm uint64
// Constant multicodec.Code values that allow Varsig implementations to
@@ -36,16 +36,15 @@ func DecodeHashAlgorithm(r *bytes.Reader) (HashAlgorithm, error) {
h := HashAlgorithm(u)
if _, ok := map[HashAlgorithm]struct{}{
HashAlgorithmSHA256: {},
HashAlgorithmSHA384: {},
HashAlgorithmSHA512: {},
HashAlgorithmShake256: {},
}[h]; !ok {
switch h {
case HashAlgorithmSHA256,
HashAlgorithmSHA384,
HashAlgorithmSHA512,
HashAlgorithmShake256:
return h, nil
default:
return HashAlgorithmUnspecified, fmt.Errorf("%w: %x", ErrUnknownHashAlgorithm, h)
}
return h, nil
}
// PayloadEncoding specifies the encoding of the data being (hashed and)
@@ -88,32 +87,30 @@ func DecodePayloadEncoding(r *bytes.Reader, vers Version) (PayloadEncoding, erro
// https://github.com/ChainAgnostic/varsig#4-payload-encoding
func decodeEncodingInfoV0(payEnc PayloadEncoding) (PayloadEncoding, error) {
if _, ok := map[PayloadEncoding]struct{}{
PayloadEncodingVerbatim: {},
PayloadEncodingDAGPB: {},
PayloadEncodingDAGCBOR: {},
PayloadEncodingDAGJSON: {},
PayloadEncodingJWT: {},
PayloadEncodingEIP191: {},
}[payEnc]; !ok {
switch payEnc {
case PayloadEncodingVerbatim,
PayloadEncodingDAGPB,
PayloadEncodingDAGCBOR,
PayloadEncodingDAGJSON,
PayloadEncodingJWT,
PayloadEncodingEIP191:
return payEnc, nil
default:
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version0, payEnc)
}
return payEnc, nil
}
// https://github.com/expede/varsig/blob/main/README.md#payload-encoding
func decodeEncodingInfoV1(payEnc PayloadEncoding) (PayloadEncoding, error) {
if _, ok := map[PayloadEncoding]struct{}{
PayloadEncodingVerbatim: {},
PayloadEncodingDAGCBOR: {},
PayloadEncodingDAGJSON: {},
PayloadEncodingEIP191: {},
}[payEnc]; !ok {
switch payEnc {
case PayloadEncodingVerbatim,
PayloadEncodingDAGCBOR,
PayloadEncodingDAGJSON,
PayloadEncodingEIP191:
return payEnc, nil
default:
return PayloadEncodingUnspecified, fmt.Errorf("%w: version=%d, encoding=%x", ErrUnsupportedPayloadEncoding, Version1, payEnc)
}
return payEnc, nil
}
// Discriminator is (usually) the multicodec.Code representing the public

View File

@@ -39,6 +39,14 @@ func TestDecodeHashAlgorithm(t *testing.T) {
})
}
func BenchmarkDecodeHashAlgorithm(b *testing.B) {
b.ReportAllocs()
data := []byte{0x12}
for i := 0; i < b.N; i++ {
_, _ = varsig.DecodeHashAlgorithm(bytes.NewReader(data))
}
}
func TestDecodePayloadEncoding(t *testing.T) {
t.Parallel()
@@ -105,3 +113,11 @@ func TestDecodePayloadEncoding(t *testing.T) {
}
})
}
func BenchmarkDecodePayloadEncoding(b *testing.B) {
b.ReportAllocs()
data := []byte{0x5f}
for i := 0; i < b.N; i++ {
_, _ = varsig.DecodePayloadEncoding(bytes.NewReader(data), varsig.Version1)
}
}