m
Some checks failed
DCO action / DCO (pull_request) Failing after 32s
Vulncheck / Vulncheck (pull_request) Successful in 1m10s
Pre-commit hooks / Pre-commit (pull_request) Successful in 1m31s
Tests and linters / Lint (pull_request) Failing after 1m59s
Tests and linters / Staticcheck (pull_request) Failing after 1m55s
Tests and linters / Tests (pull_request) Failing after 1m57s
Build / Build Components (pull_request) Successful in 2m13s
Tests and linters / Tests with -race (pull_request) Failing after 3m25s
Tests and linters / gopls check (pull_request) Successful in 3m44s
Tests and linters / Run gofumpt (pull_request) Successful in 4m37s
Some checks failed
DCO action / DCO (pull_request) Failing after 32s
Vulncheck / Vulncheck (pull_request) Successful in 1m10s
Pre-commit hooks / Pre-commit (pull_request) Successful in 1m31s
Tests and linters / Lint (pull_request) Failing after 1m59s
Tests and linters / Staticcheck (pull_request) Failing after 1m55s
Tests and linters / Tests (pull_request) Failing after 1m57s
Build / Build Components (pull_request) Successful in 2m13s
Tests and linters / Tests with -race (pull_request) Failing after 3m25s
Tests and linters / gopls check (pull_request) Successful in 3m44s
Tests and linters / Run gofumpt (pull_request) Successful in 4m37s
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
eb8b0a6999
commit
1ec5377241
2 changed files with 143 additions and 10 deletions
|
@ -2,11 +2,10 @@ package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/util/proto"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/VictoriaMetrics/easyproto"
|
"github.com/VictoriaMetrics/easyproto"
|
||||||
)
|
)
|
||||||
|
@ -174,18 +173,89 @@ func attributeValueRaw(src []byte, attribute string) (attributeMatchResult, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
func parentFromChild(src []byte) ([]byte, error) {
|
func parentFromChild(src []byte) ([]byte, error) {
|
||||||
child := objectSDK.New()
|
iter := newProtoIter(src, true)
|
||||||
|
for iter.next(); !iter.finished(); iter.next() {
|
||||||
|
if iter.fc.FieldNum == 3 {
|
||||||
|
return parentFromChildHeader(iter.fc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||||
|
}
|
||||||
|
|
||||||
err := child.Unmarshal(src)
|
func parentFromChildHeader(fc easyproto.FieldContext) ([]byte, error) {
|
||||||
if err != nil {
|
iter := newProtoIter(fc.MessageData())
|
||||||
return nil, fmt.Errorf("unmarshal child with parent: %w", err)
|
for iter.next(); !iter.finished(); iter.next() {
|
||||||
|
if iter.fc.FieldNum == 11 {
|
||||||
|
return parentFromSplitHeader(iter.fc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||||
|
}
|
||||||
|
|
||||||
|
func parentFromSplitHeader(fc easyproto.FieldContext) ([]byte, error) {
|
||||||
|
iter := newProtoIter(fc.MessageData())
|
||||||
|
|
||||||
|
var parentID, parentSig, parentHdr []byte
|
||||||
|
for iter.next(); !iter.finished(); iter.next() {
|
||||||
|
var ok bool
|
||||||
|
switch iter.fc.FieldNum {
|
||||||
|
case 1: // parent id
|
||||||
|
parentID, ok = iter.fc.MessageData()
|
||||||
|
case 3: // parent signature
|
||||||
|
parentSig, ok = iter.fc.MessageData()
|
||||||
|
case 4: // parent header
|
||||||
|
parentHdr, ok = iter.fc.MessageData()
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return nil, errMalformedObject
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
par := child.Parent()
|
if parentSig == nil || parentHdr == nil {
|
||||||
|
|
||||||
if par == nil { // this should never happen though
|
|
||||||
return nil, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
return nil, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||||
}
|
}
|
||||||
|
|
||||||
return par.Marshal()
|
h := &header{
|
||||||
|
parentID: parentID,
|
||||||
|
parentSig: parentSig,
|
||||||
|
parentHdr: parentHdr,
|
||||||
|
}
|
||||||
|
return h.StableMarshal(make([]byte, h.StableSize())), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
header struct {
|
||||||
|
parentID bs
|
||||||
|
parentSig bs
|
||||||
|
parentHdr bs
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (o *header) StableSize() int {
|
||||||
|
var size int
|
||||||
|
size += proto.NestedStructureSize(1, &o.parentID)
|
||||||
|
size += proto.NestedStructureSize(2, &o.parentSig)
|
||||||
|
size += proto.NestedStructureSize(3, &o.parentHdr)
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *header) StableMarshal(buf []byte) []byte {
|
||||||
|
var offset int
|
||||||
|
offset += proto.NestedStructureMarshal(1, buf[offset:], &o.parentID)
|
||||||
|
offset += proto.NestedStructureMarshal(2, buf[offset:], &o.parentSig)
|
||||||
|
offset += proto.NestedStructureMarshal(3, buf[offset:], &o.parentHdr)
|
||||||
|
return buf[:offset]
|
||||||
|
}
|
||||||
|
|
||||||
|
type bs []byte
|
||||||
|
|
||||||
|
func (b *bs) StableSize() int {
|
||||||
|
return len(*b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bs) StableMarshal(dst []byte) []byte {
|
||||||
|
copy(dst, *b)
|
||||||
|
return dst[:len(*b)]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
package meta
|
package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
|
@ -36,3 +42,60 @@ func TestAttributeValueRaw_ZeroAlloc(t *testing.T) {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkParentFromChild(b *testing.B) {
|
||||||
|
cnr := cidtest.ID()
|
||||||
|
parent := testutil.GenerateObjectWithCIDWithPayload(cnr, nil)
|
||||||
|
parent.SetPayloadSize(1234)
|
||||||
|
|
||||||
|
pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
require.NoError(b, err)
|
||||||
|
require.NoError(b, objectSDK.CalculateAndSetSignature(*pk, parent))
|
||||||
|
|
||||||
|
child := testutil.GenerateObjectWithCID(cnr)
|
||||||
|
child.SetParent(parent)
|
||||||
|
|
||||||
|
data, err := child.Marshal()
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
o1, err := parentFromChildUnoptimized(data)
|
||||||
|
require.NoError(b, err)
|
||||||
|
o2, err := parentFromChild(data)
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
require.Equal(b, o1, o2)
|
||||||
|
|
||||||
|
b.Run("unoptimized", func(b *testing.B) {
|
||||||
|
for range b.N {
|
||||||
|
_, err := parentFromChildUnoptimized(data)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
b.Run("proto access", func(b *testing.B) {
|
||||||
|
for range b.N {
|
||||||
|
_, err := parentFromChild(data)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func parentFromChildUnoptimized(src []byte) ([]byte, error) {
|
||||||
|
child := objectSDK.New()
|
||||||
|
|
||||||
|
err := child.Unmarshal(src)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshal child with parent: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
par := child.Parent()
|
||||||
|
|
||||||
|
if par == nil { // this should never happen though
|
||||||
|
return nil, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||||
|
}
|
||||||
|
|
||||||
|
return par.Marshal()
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue