[#209] object: Support splitID search attribute

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-11-25 19:32:52 +03:00 committed by Alex Vanin
parent 79c76e87e4
commit 3d08d8140f
8 changed files with 137 additions and 13 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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(
GetHeader(). (*object.Object)(o).
GetSplit(). GetHeader().
GetSplitID() GetSplit().
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())
}) })
} }

View file

@ -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)
}

View file

@ -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
View 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
}

View 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())
})
}

View file

@ -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 (