forked from TrueCloudLab/frostfs-api-go
[#209] object: Support splitID
search attribute
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
79c76e87e4
commit
3d08d8140f
8 changed files with 137 additions and 13 deletions
|
@ -111,8 +111,8 @@ func (o *RawObject) SetChildren(v ...*ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSplitID sets split identifier for the split object.
|
// SetSplitID sets split identifier for the split object.
|
||||||
func (o *RawObject) SetSplitID(v []byte) {
|
func (o *RawObject) SetSplitID(id *SplitID) {
|
||||||
o.setSplitID(v)
|
o.setSplitID(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetParentID sets identifier of the parent object.
|
// SetParentID sets identifier of the parent object.
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
|
@ -196,9 +195,7 @@ func TestRawObject_SetSplitID(t *testing.T) {
|
||||||
|
|
||||||
require.Nil(t, obj.SplitID())
|
require.Nil(t, obj.SplitID())
|
||||||
|
|
||||||
splitID, err := uuid.New().MarshalBinary()
|
splitID := NewSplitID()
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
obj.SetSplitID(splitID)
|
obj.SetSplitID(splitID)
|
||||||
|
|
||||||
require.Equal(t, obj.SplitID(), splitID)
|
require.Equal(t, obj.SplitID(), splitID)
|
||||||
|
|
|
@ -253,16 +253,18 @@ func (o *rwObject) setChildren(v ...*ID) {
|
||||||
|
|
||||||
// SplitID return split identity of split object. If object is not split
|
// SplitID return split identity of split object. If object is not split
|
||||||
// returns nil.
|
// returns nil.
|
||||||
func (o *rwObject) SplitID() []byte {
|
func (o *rwObject) SplitID() *SplitID {
|
||||||
return (*object.Object)(o).
|
return NewSplitIDFromV2(
|
||||||
|
(*object.Object)(o).
|
||||||
GetHeader().
|
GetHeader().
|
||||||
GetSplit().
|
GetSplit().
|
||||||
GetSplitID()
|
GetSplitID(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *rwObject) setSplitID(id []byte) {
|
func (o *rwObject) setSplitID(id *SplitID) {
|
||||||
o.setSplitFields(func(split *object.SplitHeader) {
|
o.setSplitFields(func(split *object.SplitHeader) {
|
||||||
split.SetSplitID(id)
|
split.SetSplitID(id.ToV2())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ const (
|
||||||
fKeyType
|
fKeyType
|
||||||
fKeyHomomorphicHash
|
fKeyHomomorphicHash
|
||||||
fKeyParent
|
fKeyParent
|
||||||
|
fKeySplitID
|
||||||
fKeyPropRoot
|
fKeyPropRoot
|
||||||
fKeyPropPhy
|
fKeyPropPhy
|
||||||
)
|
)
|
||||||
|
@ -98,6 +99,8 @@ func (k filterKey) String() string {
|
||||||
return v2object.FilterHeaderHomomorphicHash
|
return v2object.FilterHeaderHomomorphicHash
|
||||||
case fKeyParent:
|
case fKeyParent:
|
||||||
return v2object.FilterHeaderParent
|
return v2object.FilterHeaderParent
|
||||||
|
case fKeySplitID:
|
||||||
|
return v2object.FilterHeaderSplitID
|
||||||
case fKeyPropRoot:
|
case fKeyPropRoot:
|
||||||
return v2object.FilterPropertyRoot
|
return v2object.FilterPropertyRoot
|
||||||
case fKeyPropPhy:
|
case fKeyPropPhy:
|
||||||
|
@ -224,6 +227,7 @@ func (f *SearchFilters) AddPhyFilter() {
|
||||||
f.addPhyFilter()
|
f.addPhyFilter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddParentIDFilter adds filter by parent identifier.
|
||||||
func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id *ID) {
|
func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id *ID) {
|
||||||
f.addReservedFilter(m, fKeyParent, id)
|
f.addReservedFilter(m, fKeyParent, id)
|
||||||
}
|
}
|
||||||
|
@ -232,3 +236,7 @@ func (f *SearchFilters) AddParentIDFilter(m SearchMatchType, id *ID) {
|
||||||
func (f *SearchFilters) AddObjectIDFilter(m SearchMatchType, id *ID) {
|
func (f *SearchFilters) AddObjectIDFilter(m SearchMatchType, id *ID) {
|
||||||
f.addReservedFilter(m, fKeyObjectID, id)
|
f.addReservedFilter(m, fKeyObjectID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *SearchFilters) AddSplitIDFilter(m SearchMatchType, id *SplitID) {
|
||||||
|
f.addReservedFilter(m, fKeySplitID, id)
|
||||||
|
}
|
||||||
|
|
|
@ -123,3 +123,20 @@ func TestSearchFilters_AddObjectIDFilter(t *testing.T) {
|
||||||
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSearchFilters_AddSplitIDFilter(t *testing.T) {
|
||||||
|
id := object.NewSplitID()
|
||||||
|
|
||||||
|
fs := new(object.SearchFilters)
|
||||||
|
fs.AddSplitIDFilter(object.MatchStringEqual, id)
|
||||||
|
|
||||||
|
t.Run("v2", func(t *testing.T) {
|
||||||
|
fsV2 := fs.ToV2()
|
||||||
|
|
||||||
|
require.Len(t, fsV2, 1)
|
||||||
|
|
||||||
|
require.Equal(t, v2object.FilterHeaderSplitID, fsV2[0].GetKey())
|
||||||
|
require.Equal(t, id.String(), fsV2[0].GetValue())
|
||||||
|
require.Equal(t, v2object.MatchStringEqual, fsV2[0].GetMatchType())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
59
pkg/object/splitid.go
Normal file
59
pkg/object/splitid.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package object
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SplitID is a UUIDv4 used as attribute in split objects.
|
||||||
|
type SplitID struct {
|
||||||
|
uuid uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSplitID returns UUID representation of splitID attribute.
|
||||||
|
func NewSplitID() *SplitID {
|
||||||
|
return &SplitID{
|
||||||
|
uuid: uuid.New(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSplitIDFromV2 returns parsed UUID from bytes.
|
||||||
|
// If v is invalid UUIDv4 byte sequence, then function returns nil.
|
||||||
|
func NewSplitIDFromV2(v []byte) *SplitID {
|
||||||
|
id := uuid.New()
|
||||||
|
|
||||||
|
err := id.UnmarshalBinary(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SplitID{
|
||||||
|
uuid: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse converts UUIDv4 string representation into SplitID.
|
||||||
|
func (id *SplitID) Parse(s string) (err error) {
|
||||||
|
id.uuid, err = uuid.Parse(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns UUIDv4 string representation of SplitID.
|
||||||
|
func (id SplitID) String() string {
|
||||||
|
return id.uuid.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUUID sets pre created UUID structure as SplitID.
|
||||||
|
func (id *SplitID) SetUUID(v uuid.UUID) {
|
||||||
|
id.uuid = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToV2 converts SplitID to a representation of SplitID in neofs-api v2.
|
||||||
|
func (id SplitID) ToV2() []byte {
|
||||||
|
data, _ := id.uuid.MarshalBinary() // err is always nil
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
38
pkg/object/splitid_test.go
Normal file
38
pkg/object/splitid_test.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package object_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSplitID(t *testing.T) {
|
||||||
|
id := object.NewSplitID()
|
||||||
|
|
||||||
|
t.Run("toV2/fromV2", func(t *testing.T) {
|
||||||
|
data := id.ToV2()
|
||||||
|
|
||||||
|
newID := object.NewSplitIDFromV2(data)
|
||||||
|
require.NotNil(t, newID)
|
||||||
|
|
||||||
|
require.Equal(t, id, newID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("string/parse", func(t *testing.T) {
|
||||||
|
idStr := id.String()
|
||||||
|
|
||||||
|
newID := object.NewSplitID()
|
||||||
|
require.NoError(t, newID.Parse(idStr))
|
||||||
|
|
||||||
|
require.Equal(t, id, newID)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("set UUID", func(t *testing.T) {
|
||||||
|
newUUID := uuid.New()
|
||||||
|
id.SetUUID(newUUID)
|
||||||
|
|
||||||
|
require.Equal(t, newUUID.String(), id.String())
|
||||||
|
})
|
||||||
|
}
|
|
@ -33,6 +33,9 @@ const (
|
||||||
|
|
||||||
// FilterHeaderParent is a filter key to "split.parent" field of the object header.
|
// FilterHeaderParent is a filter key to "split.parent" field of the object header.
|
||||||
FilterHeaderParent = ReservedFilterPrefix + "split.parent"
|
FilterHeaderParent = ReservedFilterPrefix + "split.parent"
|
||||||
|
|
||||||
|
// FilterHeaderParent is a filter key to "split.splitID" field of the object header.
|
||||||
|
FilterHeaderSplitID = ReservedFilterPrefix + "split.splitID"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
Loading…
Reference in a new issue