Use protowire in util/proto helpers #50

Closed
opened 2023-07-26 15:35:08 +00:00 by fyrchik · 5 comments
Owner

It has almost everything we need https://pkg.go.dev/google.golang.org/protobuf@v1.31.0/encoding/protowire#SizeVarint
And communicates our intentions somewhat more clearly. Also, helps to get rid of all these << | bit trickery.

It has almost everything we need https://pkg.go.dev/google.golang.org/protobuf@v1.31.0/encoding/protowire#SizeVarint And communicates our intentions somewhat more clearly. Also, helps to get rid of all these `<< |` bit trickery.
aarifullin self-assigned this 2023-08-02 07:32:56 +00:00
Author
Owner

After this we can change protogen and, possibly, replace api-go dependency with protowire

After this we can change `protogen` and, possibly, replace `api-go` dependency with `protowire`
fyrchik reopened this issue 2023-08-11 07:34:32 +00:00
Author
Owner

We still have a bunch of opportunities for protowire.AppendBytes etc.
Let's benchmark and replace if possible.

We still have a bunch of opportunities for `protowire.AppendBytes` etc. Let's benchmark and replace if possible.
Member

We still have a bunch of opportunities for protowire.AppendBytes etc.
Let's benchmark and replace if possible.

Ah, ok! But we need take in count that it requires some refactoring for StableMarshaller interface to make it possible to use AppendBytes

> We still have a bunch of opportunities for `protowire.AppendBytes` etc. > Let's benchmark and replace if possible. Ah, ok! But we need take in count that it requires some refactoring for StableMarshaller interface to make it possible to use `AppendBytes`
Author
Owner

Not necessary: copy(a, b) can be replaced with append(a[:0], b...), but let's check whether it is slower.

Not necessary: `copy(a, b)` can be replaced with `append(a[:0], b...)`, but let's check whether it is slower.
Member

The pull-request #56 demonstrates why using protowire.Append... methods is not good idea.

All api-defined types must impelement StableMarshal([]byte) []byte) method (to implement StableMarshaller interface)

When a primitive numeric type is going to be serialized, these methods are used:

  1. UInt64Marshal
  2. Int64Marshal
    ...

As you can see, these methods return the offset.

If we consider the idea of using StableMarshal, then we can see that we should allocate a slice with defined length (make([]byte, N) and then we shift the offset for each internal StableMarshal invocation (io.Write behaves in the same way)

protowire.Append... method oblige us to allocate a slice with defined capacity with 0 length (make([]byte, 0, N). So, when we go down to UInt64Marshal or Int64Marshal we need to make these methods return the slice instead the offset. Such refactoring breaks frostfs-node because there are methods for protobufs that are generated by protoc plugin.

We want to keep the same interface and support backward compability. However, another good idea comes up - we may refactor StableMarshal to Write and make types implement io.Writer interface that can be very useful

The pull-request [#56](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/pulls/56) demonstrates why using `protowire.Append...` methods is not good idea. All api-defined types must impelement `StableMarshal([]byte) []byte)` method (to implement `StableMarshaller` interface) When a primitive numeric type is going to be serialized, these methods are used: 1. [UInt64Marshal](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/src/branch/master/util/proto/marshal.go#L94) 2. [Int64Marshal](https://git.frostfs.info/TrueCloudLab/frostfs-api-go/src/branch/master/util/proto/marshal.go#L116) ... As you can see, these methods return **the offset**. If we consider the idea of using `StableMarshal`, then we can see that we should allocate a slice with defined **length** (`make([]byte, N`) and then we shift the offset for each internal `StableMarshal` invocation (`io.Write` behaves in the same way) `protowire.Append...` method oblige us to allocate a slice with defined capacity with 0 length (`make([]byte, 0, N`). So, when we go down to `UInt64Marshal` or `Int64Marshal` we need to make these methods return the slice instead the offset. Such refactoring breaks `frostfs-node` because there are methods for protobufs that are generated by protoc plugin. We want to keep the same interface and support backward compability. However, another good idea comes up - we may refactor `StableMarshal` to `Write` and make types implement `io.Writer` interface that can be very useful
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: TrueCloudLab/frostfs-api-go#50
No description provided.