Skip to content

Commit

Permalink
Fix ROOT filter for SearchV2 (#3166)
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-khimov authored Feb 21, 2025
2 parents d9c3652 + 032e3a9 commit 69e69fb
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 18 deletions.
8 changes: 4 additions & 4 deletions pkg/local_object_storage/metabase/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func invalidMetaBucketKeyErr(key []byte, cause error) error {
return fmt.Errorf("invalid meta bucket key (prefix 0x%X): %w", key[0], cause)
}

func putMetadataForObject(tx *bbolt.Tx, hdr object.Object, root, phy bool) error {
func putMetadataForObject(tx *bbolt.Tx, hdr object.Object, hasParent, phy bool) error {
owner := hdr.Owner()
if owner.IsZero() {
return fmt.Errorf("invalid owner: %w", user.ErrZeroID)
Expand All @@ -66,12 +66,12 @@ func putMetadataForObject(tx *bbolt.Tx, hdr object.Object, root, phy bool) error
pldHmmHash = h.Value()
}
return putMetadata(tx, hdr.GetContainerID(), hdr.GetID(), ver, owner, hdr.Type(), hdr.CreationEpoch(), hdr.PayloadSize(), pldHash.Value(),
pldHmmHash, hdr.SplitID().ToV2(), hdr.GetParentID(), hdr.GetFirstID(), hdr.Attributes(), root, phy)
pldHmmHash, hdr.SplitID().ToV2(), hdr.GetParentID(), hdr.GetFirstID(), hdr.Attributes(), hasParent, phy)
}

func putMetadata(tx *bbolt.Tx, cnr cid.ID, id oid.ID, ver version.Version, owner user.ID, typ object.Type, creationEpoch uint64,
payloadLen uint64, pldHash, pldHmmHash, splitID []byte, parentID, firstID oid.ID, attrs []object.Attribute,
root, phy bool) error {
hasParent, phy bool) error {
metaBkt, err := tx.CreateBucketIfNotExists(metaBucketKey(cnr))
if err != nil {
return fmt.Errorf("create meta bucket for container: %w", err)
Expand Down Expand Up @@ -119,7 +119,7 @@ func putMetadata(tx *bbolt.Tx, cnr cid.ID, id oid.ID, ver version.Version, owner
return err
}
}
if root {
if !hasParent && typ == object.TypeRegular {
if err = putPlainAttribute(metaBkt, &keyBuf, id, object.FilterRoot, binPropMarker); err != nil {
return err
}
Expand Down
20 changes: 12 additions & 8 deletions pkg/local_object_storage/metabase/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,32 @@ func appendAttribute(obj *object.Object, k, v string) {
obj.SetAttributes(append(obj.Attributes(), *object.NewAttribute(k, v))...)
}

func assertAttrIDPrefixed[T string | []byte](t testing.TB, mb *bbolt.Bucket, id oid.ID, prefix byte, attr string, val T) {
func assertPrefixedAttrIDPresence[T string | []byte](t testing.TB, mb *bbolt.Bucket, id oid.ID, prefix byte, attr string, val T, exp bool) {
k := []byte{prefix}
k = append(k, attr...)
k = append(k, 0xFF)
k = append(k, val...)
k = append(k, id[:]...)
require.Equal(t, []byte{}, mb.Get(k))
require.Equal(t, exp, mb.Get(k) != nil)
}

func assertAttr[T string | []byte](t testing.TB, mb *bbolt.Bucket, id oid.ID, attr string, val T) {
assertAttrIDPrefixed(t, mb, id, 0x02, attr, val)
func assertAttrPresence[T string | []byte](t testing.TB, mb *bbolt.Bucket, id oid.ID, attr string, val T, exp bool) {
assertPrefixedAttrIDPresence(t, mb, id, 0x02, attr, val, exp)
k := []byte{0x03}
k = append(k, id[:]...)
k = append(k, attr...)
k = append(k, 0xFF)
k = append(k, val...)
require.Equal(t, []byte{}, mb.Get(k))
require.Equal(t, exp, mb.Get(k) != nil)
}

func assertAttr[T string | []byte](t testing.TB, mb *bbolt.Bucket, id oid.ID, attr string, val T) {
assertAttrPresence(t, mb, id, attr, val, true)
}

func assertIntAttr(t testing.TB, mb *bbolt.Bucket, id oid.ID, attr string, origin string, val []byte) {
assertAttr(t, mb, id, attr, origin)
assertAttrIDPrefixed(t, mb, id, 0x01, attr, val)
assertPrefixedAttrIDPresence(t, mb, id, 0x01, attr, val, true)
}

func TestPutMetadata(t *testing.T) {
Expand Down Expand Up @@ -129,7 +133,7 @@ func TestPutMetadata(t *testing.T) {
0, 0, 0, 0, 101, 118, 30, 154, 145, 227, 159, 231})
assertIntAttr(t, mb, id, "$Object:payloadLength", "2091724451450177666", []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 29, 7, 76, 78, 96, 175, 200, 130})
assertAttr(t, mb, id, "$Object:ROOT", "1")
assertAttrPresence(t, mb, id, "$Object:ROOT", "1", false)
assertAttr(t, mb, id, "$Object:PHY", "1")
assertAttr(t, mb, id, "attr_1", "val_1")
assertAttr(t, mb, id, "attr_2", "val_2")
Expand Down Expand Up @@ -677,7 +681,7 @@ func TestDB_SearchObjects(t *testing.T) {
object.MatchUnspecified, object.MatchStringEqual, object.MatchStringNotEqual,
object.MatchNumGT, object.MatchNumGE, object.MatchNumLT, object.MatchNumLE,
} {
check("$Object:ROOT", matcher, "", []uint{0, 1})
check("$Object:ROOT", matcher, "", []uint{0})
}
check("$Object:ROOT", object.MatchNotPresent, "", nil)
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/local_object_storage/metabase/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (db *DB) put(
pldHmmHash = h.Value()
}
if err := putMetadata(tx, cnr, obj.GetID(), ver, *owner, obj.Type(), obj.CreationEpoch(), obj.PayloadSize(),
pldHash.Value(), pldHmmHash, obj.SplitID().ToV2(), obj.GetParentID(), obj.GetFirstID(), obj.Attributes(), par == nil, !isParent); err != nil {
pldHash.Value(), pldHmmHash, obj.SplitID().ToV2(), obj.GetParentID(), obj.GetFirstID(), obj.Attributes(), par != nil, !isParent); err != nil {
return fmt.Errorf("put metadata: %w", err)
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/local_object_storage/metabase/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,12 @@ func migrateFrom3Version(_ *DB, tx *bbolt.Tx) error {
return fmt.Errorf("decode header of object %s from bucket value: %w", id, err)
}
par := hdr.Parent()
if err := putMetadataForObject(tx, hdr, par == nil, true); err != nil {
hasParent := par != nil
if err := putMetadataForObject(tx, hdr, hasParent, true); err != nil {
return fmt.Errorf("put metadata for object %s: %w", id, err)
}
if par != nil {
if err := putMetadataForObject(tx, *par, true, false); err != nil {
if hasParent {
if err := putMetadataForObject(tx, *par, false, false); err != nil {
return fmt.Errorf("put metadata for parent of object %s: %w", id, err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/local_object_storage/metabase/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,11 +563,11 @@ func TestMigrate3to4(t *testing.T) {
fs.AddRootFilter()
res, _, err = db.Search(objs[i].GetContainerID(), fs, nil, nil, nil, 1000)
require.NoError(t, err, i)
require.Len(t, res, 1, i)
if i == 0 {
require.Len(t, res, 1)
require.Equal(t, par.GetID(), res[0].ID)
} else {
require.Equal(t, objs[i].GetID(), res[0].ID, i)
require.Empty(t, res, i)
}
fs = fs[:0]
fs.AddPhyFilter()
Expand Down

0 comments on commit 69e69fb

Please sign in to comment.