From 9a7b47d769c5087a46d6785aa0ac6696027e9d95 Mon Sep 17 00:00:00 2001 From: Airat Arifullin Date: Wed, 2 Aug 2023 16:53:47 +0300 Subject: [PATCH] [#50] util: Use protowire for util/proto helpers * Use methods to calculate size Signed-off-by: Airat Arifullin a.arifullin@yadro.com --- refs/marshal.go | 3 +- util/proto/marshal.go | 73 ++++++++++++++----------------------------- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/refs/marshal.go b/refs/marshal.go index 03821901..ef197b37 100644 --- a/refs/marshal.go +++ b/refs/marshal.go @@ -6,6 +6,7 @@ import ( refs "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto" + "google.golang.org/protobuf/encoding/protowire" ) const ( @@ -116,7 +117,7 @@ func (o *ObjectID) StableSize() int { // ObjectIDNestedListMarshal writes protobuf repeated ObjectID field // with fNum number to buf. func ObjectIDNestedListMarshal(fNum int64, buf []byte, ids []ObjectID) (off int) { - prefix, _ := proto.NestedStructurePrefix(fNum) + prefix := protowire.EncodeTag(protowire.Number(fNum), protowire.BytesType) for i := range ids { off += binary.PutUvarint(buf[off:], prefix) diff --git a/util/proto/marshal.go b/util/proto/marshal.go index b1f55a37..606086aa 100644 --- a/util/proto/marshal.go +++ b/util/proto/marshal.go @@ -10,6 +10,8 @@ import ( "encoding/binary" "math" "math/bits" + + "google.golang.org/protobuf/encoding/protowire" ) type ( @@ -35,7 +37,7 @@ func bytesMarshal[T ~[]byte | ~string](field int, buf []byte, v T) int { } func bytesMarshalNoCheck[T ~[]byte | ~string](field int, buf []byte, v T) int { - prefix := field<<3 | 0x2 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.BytesType) // buf length check can prevent panic at PutUvarint, but it will make // marshaller a bit slower. @@ -54,9 +56,7 @@ func bytesSize[T ~[]byte | ~string](field int, v T) int { } func bytesSizeNoCheck[T ~[]byte | ~string](field int, v T) int { - prefix := field<<3 | 0x2 - - return VarUIntSize(uint64(prefix)) + VarUIntSize(uint64(len(v))) + len(v) + return protowire.SizeGroup(protowire.Number(field), protowire.SizeBytes(len(v))) } func StringMarshal(field int, buf []byte, v string) int { @@ -72,12 +72,13 @@ func BoolMarshal(field int, buf []byte, v bool) int { return 0 } - prefix := field << 3 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.VarintType) // buf length check can prevent panic at PutUvarint, but it will make // marshaller a bit slower. i := binary.PutUvarint(buf, uint64(prefix)) - buf[i] = 0x1 + const boolTrueValue = 0x1 + buf[i] = boolTrueValue return i + 1 } @@ -86,10 +87,8 @@ func BoolSize(field int, v bool) int { if !v { return 0 } - - prefix := field << 3 - - return VarUIntSize(uint64(prefix)) + 1 // bool is always 1 byte long + const boolLength = 1 + return protowire.SizeGroup(protowire.Number(field), boolLength) } func UInt64Marshal(field int, buf []byte, v uint64) int { @@ -97,7 +96,7 @@ func UInt64Marshal(field int, buf []byte, v uint64) int { return 0 } - prefix := field << 3 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.VarintType) // buf length check can prevent panic at PutUvarint, but it will make // marshaller a bit slower. @@ -111,10 +110,7 @@ func UInt64Size(field int, v uint64) int { if v == 0 { return 0 } - - prefix := field << 3 - - return VarUIntSize(uint64(prefix)) + VarUIntSize(v) + return protowire.SizeGroup(protowire.Number(field), protowire.SizeVarint(v)) } func Int64Marshal(field int, buf []byte, v int64) int { @@ -191,16 +187,12 @@ func repeatedUIntSize[T ~uint64 | ~int64 | ~uint32 | ~int32](field int, v []T) ( } for i := range v { - size += VarUIntSize(uint64(v[i])) + arraySize += protowire.SizeVarint(uint64(v[i])) } - arraySize = size - size += VarUIntSize(uint64(size)) + size = protowire.SizeGroup(protowire.Number(field), protowire.SizeBytes(arraySize)) - prefix := field<<3 | 0x2 - size += VarUIntSize(uint64(prefix)) - - return size, arraySize + return } func repeatedUIntMarshal[T ~uint64 | ~int64 | ~uint32 | ~int32](field int, buf []byte, v []T) int { @@ -208,7 +200,7 @@ func repeatedUIntMarshal[T ~uint64 | ~int64 | ~uint32 | ~int32](field int, buf [ return 0 } - prefix := field<<3 | 0x02 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.BytesType) offset := binary.PutUvarint(buf, uint64(prefix)) _, arrSize := repeatedUIntSize(field, v) @@ -257,18 +249,13 @@ func VarUIntSize(x uint64) int { return (bits.Len64(x|1) + 6) / 7 } -func NestedStructurePrefix(field int64) (prefix uint64, ln int) { - prefix = uint64(field<<3 | 0x02) - return prefix, VarUIntSize(prefix) -} - func NestedStructureMarshal[T stableMarshaller](field int64, buf []byte, v T) int { n := v.StableSize() if n == 0 { return 0 } - prefix, _ := NestedStructurePrefix(field) + prefix := protowire.EncodeTag(protowire.Number(field), protowire.BytesType) offset := binary.PutUvarint(buf, prefix) offset += binary.PutUvarint(buf[offset:], uint64(n)) v.StableMarshal(buf[offset:]) @@ -281,11 +268,8 @@ func NestedStructureSize[T stableMarshaller](field int64, v T) (size int) { if n == 0 { return 0 } - - _, ln := NestedStructurePrefix(field) - size = ln + VarUIntSize(uint64(n)) + n - - return size + size = protowire.SizeGroup(protowire.Number(field), protowire.SizeBytes(n)) + return } func Fixed64Marshal(field int, buf []byte, v uint64) int { @@ -293,7 +277,7 @@ func Fixed64Marshal(field int, buf []byte, v uint64) int { return 0 } - prefix := field<<3 | 1 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.Fixed64Type) // buf length check can prevent panic at PutUvarint, but it will make // marshaller a bit slower. @@ -307,10 +291,7 @@ func Fixed64Size(fNum int, v uint64) int { if v == 0 { return 0 } - - prefix := fNum<<3 | 1 - - return VarUIntSize(uint64(prefix)) + 8 + return protowire.SizeGroup(protowire.Number(fNum), protowire.SizeFixed64()) } func Float64Marshal(field int, buf []byte, v float64) int { @@ -318,7 +299,7 @@ func Float64Marshal(field int, buf []byte, v float64) int { return 0 } - prefix := field<<3 | 1 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.Fixed64Type) i := binary.PutUvarint(buf, uint64(prefix)) binary.LittleEndian.PutUint64(buf[i:], math.Float64bits(v)) @@ -330,10 +311,7 @@ func Float64Size(fNum int, v float64) int { if v == 0 { return 0 } - - prefix := fNum<<3 | 1 - - return VarUIntSize(uint64(prefix)) + 8 + return protowire.SizeGroup(protowire.Number(fNum), protowire.SizeFixed64()) } // Fixed32Marshal encodes uint32 value to Protocol Buffers fixed32 field with specified number, @@ -345,7 +323,7 @@ func Fixed32Marshal(field int, buf []byte, v uint32) int { return 0 } - prefix := field<<3 | 5 + prefix := protowire.EncodeTag(protowire.Number(field), protowire.Fixed32Type) // buf length check can prevent panic at PutUvarint, but it will make // marshaller a bit slower. @@ -361,8 +339,5 @@ func Fixed32Size(fNum int, v uint32) int { if v == 0 { return 0 } - - prefix := fNum<<3 | 5 - - return VarUIntSize(uint64(prefix)) + 4 + return protowire.SizeGroup(protowire.Number(fNum), protowire.SizeFixed32()) }