summaryrefslogtreecommitdiff
path: root/vendor/google.golang.org/grpc/encoding
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2021-07-02 13:03:10 +0200
committerValentin Rothberg <rothberg@redhat.com>2021-07-02 13:03:10 +0200
commit735be12481cdc3edfcbca3500172d2164255e1a3 (patch)
tree67f0ee2916812072967707ae6de779ebbcdb0476 /vendor/google.golang.org/grpc/encoding
parent7eb9ed975899ffe12fb82066aebf652444205e02 (diff)
downloadpodman-735be12481cdc3edfcbca3500172d2164255e1a3.tar.gz
podman-735be12481cdc3edfcbca3500172d2164255e1a3.tar.bz2
podman-735be12481cdc3edfcbca3500172d2164255e1a3.zip
force github.com/spf13/cobra@v1.1.3
v1.2.0 is breaking CI (see containers/podman/pull/10844). Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'vendor/google.golang.org/grpc/encoding')
-rw-r--r--vendor/google.golang.org/grpc/encoding/proto/proto.go70
1 files changed, 61 insertions, 9 deletions
diff --git a/vendor/google.golang.org/grpc/encoding/proto/proto.go b/vendor/google.golang.org/grpc/encoding/proto/proto.go
index 3009b35af..66b97a6f6 100644
--- a/vendor/google.golang.org/grpc/encoding/proto/proto.go
+++ b/vendor/google.golang.org/grpc/encoding/proto/proto.go
@@ -21,7 +21,8 @@
package proto
import (
- "fmt"
+ "math"
+ "sync"
"github.com/golang/protobuf/proto"
"google.golang.org/grpc/encoding"
@@ -37,22 +38,73 @@ func init() {
// codec is a Codec implementation with protobuf. It is the default codec for gRPC.
type codec struct{}
+type cachedProtoBuffer struct {
+ lastMarshaledSize uint32
+ proto.Buffer
+}
+
+func capToMaxInt32(val int) uint32 {
+ if val > math.MaxInt32 {
+ return uint32(math.MaxInt32)
+ }
+ return uint32(val)
+}
+
+func marshal(v interface{}, cb *cachedProtoBuffer) ([]byte, error) {
+ protoMsg := v.(proto.Message)
+ newSlice := make([]byte, 0, cb.lastMarshaledSize)
+
+ cb.SetBuf(newSlice)
+ cb.Reset()
+ if err := cb.Marshal(protoMsg); err != nil {
+ return nil, err
+ }
+ out := cb.Bytes()
+ cb.lastMarshaledSize = capToMaxInt32(len(out))
+ return out, nil
+}
+
func (codec) Marshal(v interface{}) ([]byte, error) {
- vv, ok := v.(proto.Message)
- if !ok {
- return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v)
+ if pm, ok := v.(proto.Marshaler); ok {
+ // object can marshal itself, no need for buffer
+ return pm.Marshal()
}
- return proto.Marshal(vv)
+
+ cb := protoBufferPool.Get().(*cachedProtoBuffer)
+ out, err := marshal(v, cb)
+
+ // put back buffer and lose the ref to the slice
+ cb.SetBuf(nil)
+ protoBufferPool.Put(cb)
+ return out, err
}
func (codec) Unmarshal(data []byte, v interface{}) error {
- vv, ok := v.(proto.Message)
- if !ok {
- return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)
+ protoMsg := v.(proto.Message)
+ protoMsg.Reset()
+
+ if pu, ok := protoMsg.(proto.Unmarshaler); ok {
+ // object can unmarshal itself, no need for buffer
+ return pu.Unmarshal(data)
}
- return proto.Unmarshal(data, vv)
+
+ cb := protoBufferPool.Get().(*cachedProtoBuffer)
+ cb.SetBuf(data)
+ err := cb.Unmarshal(protoMsg)
+ cb.SetBuf(nil)
+ protoBufferPool.Put(cb)
+ return err
}
func (codec) Name() string {
return Name
}
+
+var protoBufferPool = &sync.Pool{
+ New: func() interface{} {
+ return &cachedProtoBuffer{
+ Buffer: proto.Buffer{},
+ lastMarshaledSize: 16,
+ }
+ },
+}