forked from TrueCloudLab/frostfs-api-go
Evgenii Stratonikov
5e1c6a908f
``` goos: linux goarch: amd64 pkg: git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz │ old │ new │ │ sec/op │ sec/op vs base │ ObjectIDSlice/0_elements/to_grpc_message-8 3.193n ± 2% 3.242n ± 0% +1.50% (p=0.034 n=10) ObjectIDSlice/0_elements/from_grpc_message-8 3.197n ± 2% 3.343n ± 1% +4.57% (p=0.000 n=10) ObjectIDSlice/0_elements/marshal-8 5.666n ± 3% 5.642n ± 0% -0.42% (p=0.000 n=10) ObjectIDSlice/1_elements/to_grpc_message-8 53.10n ± 6% 29.78n ± 12% -43.92% (p=0.000 n=10) ObjectIDSlice/1_elements/from_grpc_message-8 28.99n ± 5% 29.77n ± 7% ~ (p=0.165 n=10) ObjectIDSlice/1_elements/marshal-8 49.08n ± 7% 50.72n ± 6% ~ (p=0.218 n=10) ObjectIDSlice/50_elements/to_grpc_message-8 1652.5n ± 7% 277.2n ± 1% -83.22% (p=0.000 n=10) ObjectIDSlice/50_elements/from_grpc_message-8 261.2n ± 11% 226.7n ± 15% -13.19% (p=0.003 n=10) ObjectIDSlice/50_elements/marshal-8 1.512µ ± 6% 1.514µ ± 6% ~ (p=0.955 n=10) geomean 52.15n 39.99n -23.31% │ old │ new │ │ B/op │ B/op vs base │ ObjectIDSlice/0_elements/to_grpc_message-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/0_elements/from_grpc_message-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/0_elements/marshal-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/1_elements/to_grpc_message-8 32.00 ± 0% 24.00 ± 0% -25.00% (p=0.000 n=10) ObjectIDSlice/1_elements/from_grpc_message-8 24.00 ± 0% 24.00 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/1_elements/marshal-8 48.00 ± 0% 48.00 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/50_elements/to_grpc_message-8 1.578Ki ± 0% 1.250Ki ± 0% -20.79% (p=0.000 n=10) ObjectIDSlice/50_elements/from_grpc_message-8 1.250Ki ± 0% 1.250Ki ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/50_elements/marshal-8 2.000Ki ± 0% 2.000Ki ± 0% ~ (p=1.000 n=10) ¹ geomean ² -5.62% ² ¹ all samples are equal ² summaries must be >0 to compute geomean │ old │ new │ │ allocs/op │ allocs/op vs base │ ObjectIDSlice/0_elements/to_grpc_message-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/0_elements/from_grpc_message-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/0_elements/marshal-8 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/1_elements/to_grpc_message-8 2.000 ± 0% 1.000 ± 0% -50.00% (p=0.000 n=10) ObjectIDSlice/1_elements/from_grpc_message-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/1_elements/marshal-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/50_elements/to_grpc_message-8 51.000 ± 0% 1.000 ± 0% -98.04% (p=0.000 n=10) ObjectIDSlice/50_elements/from_grpc_message-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ ObjectIDSlice/50_elements/marshal-8 1.000 ± 0% 1.000 ± 0% ~ (p=1.000 n=10) ¹ geomean ² -40.18% ² ¹ all samples are equal ² summaries must be >0 to compute geomean ``` Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
160 lines
3.3 KiB
Go
160 lines
3.3 KiB
Go
package object
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
lock "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/lock/grpc"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
|
refsGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs/grpc"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/grpc"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
|
|
)
|
|
|
|
// Lock represents object Lock message from NeoFS API V2 protocol.
|
|
type Lock struct {
|
|
members []refs.ObjectID
|
|
}
|
|
|
|
// NumberOfMembers returns length of lock list.
|
|
func (x *Lock) NumberOfMembers() int {
|
|
if x != nil {
|
|
return len(x.members)
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
// IterateMembers passes members of the lock list to f.
|
|
func (x *Lock) IterateMembers(f func(refs.ObjectID)) {
|
|
if x != nil {
|
|
for i := range x.members {
|
|
f(x.members[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
// SetMembers sets list of locked members.
|
|
// Arg must not be mutated for the duration of the Lock.
|
|
func (x *Lock) SetMembers(ids []refs.ObjectID) {
|
|
x.members = ids
|
|
}
|
|
|
|
const (
|
|
_ = iota
|
|
fNumLockMembers
|
|
)
|
|
|
|
// StableMarshal encodes the Lock into Protocol Buffers binary format
|
|
// with direct field order.
|
|
func (x *Lock) StableMarshal(buf []byte) []byte {
|
|
if x == nil || len(x.members) == 0 {
|
|
return []byte{}
|
|
}
|
|
|
|
if buf == nil {
|
|
buf = make([]byte, x.StableSize())
|
|
}
|
|
|
|
var offset int
|
|
|
|
for i := range x.members {
|
|
offset += proto.NestedStructureMarshal(fNumLockMembers, buf[offset:], &x.members[i])
|
|
}
|
|
|
|
return buf
|
|
}
|
|
|
|
// StableSize size of the buffer required to write the Lock in Protocol Buffers
|
|
// binary format.
|
|
func (x *Lock) StableSize() (sz int) {
|
|
if x != nil {
|
|
for i := range x.members {
|
|
sz += proto.NestedStructureSize(fNumLockMembers, &x.members[i])
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Unmarshal decodes the Lock from its Protocol Buffers binary format.
|
|
func (x *Lock) Unmarshal(data []byte) error {
|
|
return message.Unmarshal(x, data, new(lock.Lock))
|
|
}
|
|
|
|
func (x *Lock) ToGRPCMessage() grpc.Message {
|
|
var m *lock.Lock
|
|
|
|
if x != nil {
|
|
m = new(lock.Lock)
|
|
|
|
var members []refsGRPC.ObjectID
|
|
|
|
if x.members != nil {
|
|
members = make([]refsGRPC.ObjectID, len(x.members))
|
|
|
|
for i := range x.members {
|
|
members[i] = *x.members[i].ToGRPCMessage().(*refsGRPC.ObjectID)
|
|
}
|
|
}
|
|
|
|
m.SetMembers(members)
|
|
}
|
|
|
|
return m
|
|
}
|
|
|
|
func (x *Lock) FromGRPCMessage(m grpc.Message) error {
|
|
v, ok := m.(*lock.Lock)
|
|
if !ok {
|
|
return message.NewUnexpectedMessageType(m, v)
|
|
}
|
|
|
|
members := v.GetMembers()
|
|
if members == nil {
|
|
x.members = nil
|
|
} else {
|
|
x.members = make([]refs.ObjectID, len(members))
|
|
var err error
|
|
|
|
for i := range x.members {
|
|
err = x.members[i].FromGRPCMessage(&members[i])
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// WriteLock writes Lock to the Object as a payload content.
|
|
// The object must not be nil.
|
|
func WriteLock(obj *Object, lock Lock) {
|
|
hdr := obj.GetHeader()
|
|
if hdr == nil {
|
|
hdr = new(Header)
|
|
obj.SetHeader(hdr)
|
|
}
|
|
|
|
hdr.SetObjectType(TypeLock)
|
|
|
|
payload := lock.StableMarshal(nil)
|
|
obj.SetPayload(payload)
|
|
}
|
|
|
|
// ReadLock reads Lock from the Object payload content.
|
|
func ReadLock(lock *Lock, obj Object) error {
|
|
payload := obj.GetPayload()
|
|
if len(payload) == 0 {
|
|
return errors.New("empty payload")
|
|
}
|
|
|
|
err := lock.Unmarshal(payload)
|
|
if err != nil {
|
|
return fmt.Errorf("decode lock content from payload: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|