[#237] metabase: Structure parameters and results of all operations

All parameters and resulting values of all metabase operations are
structured in new types. The most popular scenarios for using operations are
moved to auxiliary functions.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-12-08 12:56:14 +03:00 committed by Alex Vanin
parent a875d80491
commit 590745204c
28 changed files with 482 additions and 125 deletions

View file

@ -6,8 +6,15 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
func (db *DB) CleanUp() error { // CleanUpPrm groups the parameters of CleanUp operation.
return db.boltDB.Update(func(tx *bbolt.Tx) error { type CleanUpPrm struct{}
// CleanUpRes groups resulting values of CleanUp operation.
type CleanUpRes struct{}
// CleanUp removes empty buckets from metabase.
func (db *DB) CleanUp(prm *CleanUpPrm) (res *CleanUpRes, err error) {
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
return tx.ForEach(func(name []byte, b *bbolt.Bucket) error { return tx.ForEach(func(name []byte, b *bbolt.Bucket) error {
switch { switch {
case isFKBTBucket(name): case isFKBTBucket(name):
@ -21,6 +28,8 @@ func (db *DB) CleanUp() error {
return nil return nil
}) })
}) })
return
} }
func isFKBTBucket(name []byte) bool { func isFKBTBucket(name []byte) bool {

View file

@ -19,7 +19,7 @@ func TestDB_Containers(t *testing.T) {
cids[obj.ContainerID().String()] = 0 cids[obj.ContainerID().String()] = 0
err := db.Put(obj.Object(), nil) err := putBig(db, obj.Object())
require.NoError(t, err) require.NoError(t, err)
} }

View file

@ -17,8 +17,13 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// saves "big" object in DB.
func putBig(db *meta.DB, obj *object.Object) error {
return meta.Put(db, obj, nil)
}
func testSelect(t *testing.T, db *meta.DB, fs objectSDK.SearchFilters, exp ...*objectSDK.Address) { func testSelect(t *testing.T, db *meta.DB, fs objectSDK.SearchFilters, exp ...*objectSDK.Address) {
res, err := db.Select(fs) res, err := meta.Select(db, fs)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, res, len(exp)) require.Len(t, res, len(exp))

View file

@ -10,13 +10,38 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// DeletePrm groups the parameters of Delete operation.
type DeletePrm struct {
addrs []*objectSDK.Address
}
// DeleteRes groups resulting values of Delete operation.
type DeleteRes struct{}
var ErrVirtualObject = errors.New("do not remove virtual object directly") var ErrVirtualObject = errors.New("do not remove virtual object directly")
// WithAddresses is a Delete option to set the addresses of the objects to delete.
//
// Option is required.
func (p *DeletePrm) WithAddresses(addrs ...*objectSDK.Address) *DeletePrm {
if p != nil {
p.addrs = addrs
}
return p
}
// Delete removes objects from DB.
func Delete(db *DB, addrs ...*objectSDK.Address) error {
_, err := db.Delete(new(DeletePrm).WithAddresses(addrs...))
return err
}
// DeleteObjects marks list of objects as deleted. // DeleteObjects marks list of objects as deleted.
func (db *DB) Delete(lst ...*objectSDK.Address) error { func (db *DB) Delete(prm *DeletePrm) (*DeleteRes, error) {
return db.boltDB.Update(func(tx *bbolt.Tx) error { return new(DeleteRes), db.boltDB.Update(func(tx *bbolt.Tx) error {
for i := range lst { for i := range prm.addrs {
err := db.delete(tx, lst[i], false) err := db.delete(tx, prm.addrs[i], false)
if err != nil { if err != nil {
return err // maybe log and continue? return err // maybe log and continue?
} }

View file

@ -3,6 +3,7 @@ package meta_test
import ( import (
"testing" "testing"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -19,42 +20,42 @@ func TestDB_Delete(t *testing.T) {
child.SetParentID(parent.ID()) child.SetParentID(parent.ID())
// put object with parent // put object with parent
err := db.Put(child.Object(), nil) err := putBig(db, child.Object())
require.NoError(t, err) require.NoError(t, err)
// fill ToMoveIt index // fill ToMoveIt index
err = db.ToMoveIt(child.Object().Address()) err = meta.ToMoveIt(db, child.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// check if Movable list is not empty // check if Movable list is not empty
l, err := db.Movable() l, err := meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, l, 1) require.Len(t, l, 1)
// inhume parent and child so they will be on graveyard // inhume parent and child so they will be on graveyard
ts := generateRawObjectWithCID(t, cid) ts := generateRawObjectWithCID(t, cid)
err = db.Inhume(child.Object().Address(), ts.Object().Address()) err = meta.Inhume(db, child.Object().Address(), ts.Object().Address())
require.NoError(t, err) require.NoError(t, err)
err = db.Inhume(child.Object().Address(), ts.Object().Address()) err = meta.Inhume(db, child.Object().Address(), ts.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// delete object // delete object
err = db.Delete(child.Object().Address()) err = meta.Delete(db, child.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// check if there is no data in Movable index // check if there is no data in Movable index
l, err = db.Movable() l, err = meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, l, 0) require.Len(t, l, 0)
// check if they removed from graveyard // check if they removed from graveyard
ok, err := db.Exists(child.Object().Address()) ok, err := meta.Exists(db, child.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.False(t, ok) require.False(t, ok)
ok, err = db.Exists(parent.Object().Address()) ok, err = meta.Exists(db, parent.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.False(t, ok) require.False(t, ok)
} }

View file

@ -9,18 +9,54 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// ExistsPrm groups the parameters of Exists operation.
type ExistsPrm struct {
addr *objectSDK.Address
}
// ExistsRes groups resulting values of Exists operation.
type ExistsRes struct {
exists bool
}
var ErrLackSplitInfo = errors.New("no split info on parent object") var ErrLackSplitInfo = errors.New("no split info on parent object")
// WithAddress is an Exists option to set object checked for existence.
func (p *ExistsPrm) WithAddress(addr *objectSDK.Address) *ExistsPrm {
if p != nil {
p.addr = addr
}
return p
}
// Exists returns the fact that the object is in the metabase.
func (p *ExistsRes) Exists() bool {
return p.exists
}
// Exists checks if object is presented in DB.
func Exists(db *DB, addr *objectSDK.Address) (bool, error) {
r, err := db.Exists(new(ExistsPrm).WithAddress(addr))
if err != nil {
return false, err
}
return r.Exists(), nil
}
// Exists returns ErrAlreadyRemoved if addr was marked as removed. Otherwise it // Exists returns ErrAlreadyRemoved if addr was marked as removed. Otherwise it
// returns true if addr is in primary index or false if it is not. // returns true if addr is in primary index or false if it is not.
func (db *DB) Exists(addr *objectSDK.Address) (exists bool, err error) { func (db *DB) Exists(prm *ExistsPrm) (res *ExistsRes, err error) {
res = new(ExistsRes)
err = db.boltDB.View(func(tx *bbolt.Tx) error { err = db.boltDB.View(func(tx *bbolt.Tx) error {
exists, err = db.exists(tx, addr) res.exists, err = db.exists(tx, prm.addr)
return err return err
}) })
return exists, err return
} }
func (db *DB) exists(tx *bbolt.Tx, addr *objectSDK.Address) (exists bool, err error) { func (db *DB) exists(tx *bbolt.Tx, addr *objectSDK.Address) (exists bool, err error) {

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -14,17 +15,17 @@ func TestDB_Exists(t *testing.T) {
t.Run("no object", func(t *testing.T) { t.Run("no object", func(t *testing.T) {
nonExist := generateRawObject(t) nonExist := generateRawObject(t)
exists, err := db.Exists(nonExist.Object().Address()) exists, err := meta.Exists(db, nonExist.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.False(t, exists) require.False(t, exists)
}) })
t.Run("regular object", func(t *testing.T) { t.Run("regular object", func(t *testing.T) {
regular := generateRawObject(t) regular := generateRawObject(t)
err := db.Put(regular.Object(), nil) err := putBig(db, regular.Object())
require.NoError(t, err) require.NoError(t, err)
exists, err := db.Exists(regular.Object().Address()) exists, err := meta.Exists(db, regular.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.True(t, exists) require.True(t, exists)
}) })
@ -33,10 +34,10 @@ func TestDB_Exists(t *testing.T) {
ts := generateRawObject(t) ts := generateRawObject(t)
ts.SetType(objectSDK.TypeTombstone) ts.SetType(objectSDK.TypeTombstone)
err := db.Put(ts.Object(), nil) err := putBig(db, ts.Object())
require.NoError(t, err) require.NoError(t, err)
exists, err := db.Exists(ts.Object().Address()) exists, err := meta.Exists(db, ts.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.True(t, exists) require.True(t, exists)
}) })
@ -45,10 +46,10 @@ func TestDB_Exists(t *testing.T) {
sg := generateRawObject(t) sg := generateRawObject(t)
sg.SetType(objectSDK.TypeStorageGroup) sg.SetType(objectSDK.TypeStorageGroup)
err := db.Put(sg.Object(), nil) err := putBig(db, sg.Object())
require.NoError(t, err) require.NoError(t, err)
exists, err := db.Exists(sg.Object().Address()) exists, err := meta.Exists(db, sg.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.True(t, exists) require.True(t, exists)
}) })
@ -61,10 +62,10 @@ func TestDB_Exists(t *testing.T) {
child.SetParent(parent.Object().SDK()) child.SetParent(parent.Object().SDK())
child.SetParentID(parent.ID()) child.SetParentID(parent.ID())
err := db.Put(child.Object(), nil) err := putBig(db, child.Object())
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exists(parent.Object().Address()) _, err = meta.Exists(db, parent.Object().Address())
var expectedErr *objectSDK.SplitInfoError var expectedErr *objectSDK.SplitInfoError
require.True(t, errors.As(err, &expectedErr)) require.True(t, errors.As(err, &expectedErr))
@ -89,13 +90,13 @@ func TestDB_Exists(t *testing.T) {
link.SetSplitID(splitID) link.SetSplitID(splitID)
t.Run("direct order", func(t *testing.T) { t.Run("direct order", func(t *testing.T) {
err := db.Put(child.Object(), nil) err := putBig(db, child.Object())
require.NoError(t, err) require.NoError(t, err)
err = db.Put(link.Object(), nil) err = putBig(db, link.Object())
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exists(parent.Object().Address()) _, err = meta.Exists(db, parent.Object().Address())
require.Error(t, err) require.Error(t, err)
si, ok := err.(*objectSDK.SplitInfoError) si, ok := err.(*objectSDK.SplitInfoError)
@ -107,13 +108,13 @@ func TestDB_Exists(t *testing.T) {
}) })
t.Run("reverse order", func(t *testing.T) { t.Run("reverse order", func(t *testing.T) {
err := db.Put(link.Object(), nil) err := meta.Put(db, link.Object(), nil)
require.NoError(t, err) require.NoError(t, err)
err = db.Put(child.Object(), nil) err = putBig(db, child.Object())
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exists(parent.Object().Address()) _, err = meta.Exists(db, parent.Object().Address())
require.Error(t, err) require.Error(t, err)
si, ok := err.(*objectSDK.SplitInfoError) si, ok := err.(*objectSDK.SplitInfoError)

View file

@ -9,15 +9,53 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// GetPrm groups the parameters of Get operation.
type GetPrm struct {
addr *objectSDK.Address
}
// GetRes groups resulting values of Get operation.
type GetRes struct {
hdr *object.Object
}
// WithAddress is a Get option to set the address of the requested object.
//
// Option is required.
func (p *GetPrm) WithAddress(addr *objectSDK.Address) *GetPrm {
if p != nil {
p.addr = addr
}
return p
}
// Header returns the requested object header.
func (r *GetRes) Header() *object.Object {
return r.hdr
}
// Get read the object from DB.
func Get(db *DB, addr *objectSDK.Address) (*object.Object, error) {
r, err := db.Get(new(GetPrm).WithAddress(addr))
if err != nil {
return nil, err
}
return r.Header(), nil
}
// Get returns object header for specified address. // Get returns object header for specified address.
func (db *DB) Get(addr *objectSDK.Address) (obj *object.Object, err error) { func (db *DB) Get(prm *GetPrm) (res *GetRes, err error) {
res = new(GetRes)
err = db.boltDB.View(func(tx *bbolt.Tx) error { err = db.boltDB.View(func(tx *bbolt.Tx) error {
obj, err = db.get(tx, addr, true) res.hdr, err = db.get(tx, prm.addr, true)
return err return err
}) })
return obj, err return
} }
func (db *DB) get(tx *bbolt.Tx, addr *objectSDK.Address, checkGraveyard bool) (*object.Object, error) { func (db *DB) get(tx *bbolt.Tx, addr *objectSDK.Address, checkGraveyard bool) (*object.Object, error) {

View file

@ -6,6 +6,7 @@ import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -20,15 +21,15 @@ func TestDB_Get(t *testing.T) {
addAttribute(raw, "foo", "bar") addAttribute(raw, "foo", "bar")
t.Run("object not found", func(t *testing.T) { t.Run("object not found", func(t *testing.T) {
_, err := db.Get(raw.Object().Address()) _, err := meta.Get(db, raw.Object().Address())
require.Error(t, err) require.Error(t, err)
}) })
t.Run("put regular object", func(t *testing.T) { t.Run("put regular object", func(t *testing.T) {
err := db.Put(raw.Object(), nil) err := putBig(db, raw.Object())
require.NoError(t, err) require.NoError(t, err)
newObj, err := db.Get(raw.Object().Address()) newObj, err := meta.Get(db, raw.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, raw.Object(), newObj) require.Equal(t, raw.Object(), newObj)
}) })
@ -37,10 +38,10 @@ func TestDB_Get(t *testing.T) {
raw.SetType(objectSDK.TypeTombstone) raw.SetType(objectSDK.TypeTombstone)
raw.SetID(testOID()) raw.SetID(testOID())
err := db.Put(raw.Object(), nil) err := putBig(db, raw.Object())
require.NoError(t, err) require.NoError(t, err)
newObj, err := db.Get(raw.Object().Address()) newObj, err := meta.Get(db, raw.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, raw.Object(), newObj) require.Equal(t, raw.Object(), newObj)
}) })
@ -49,10 +50,10 @@ func TestDB_Get(t *testing.T) {
raw.SetType(objectSDK.TypeStorageGroup) raw.SetType(objectSDK.TypeStorageGroup)
raw.SetID(testOID()) raw.SetID(testOID())
err := db.Put(raw.Object(), nil) err := putBig(db, raw.Object())
require.NoError(t, err) require.NoError(t, err)
newObj, err := db.Get(raw.Object().Address()) newObj, err := meta.Get(db, raw.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, raw.Object(), newObj) require.Equal(t, raw.Object(), newObj)
}) })
@ -66,14 +67,14 @@ func TestDB_Get(t *testing.T) {
child.SetParent(parent.Object().SDK()) child.SetParent(parent.Object().SDK())
child.SetParentID(parent.ID()) child.SetParentID(parent.ID())
err := db.Put(child.Object(), nil) err := putBig(db, child.Object())
require.NoError(t, err) require.NoError(t, err)
newParent, err := db.Get(parent.Object().Address()) newParent, err := meta.Get(db, parent.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.True(t, binaryEqual(parent.Object(), newParent)) require.True(t, binaryEqual(parent.Object(), newParent))
newChild, err := db.Get(child.Object().Address()) newChild, err := meta.Get(db, child.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.True(t, binaryEqual(child.Object(), newChild)) require.True(t, binaryEqual(child.Object(), newChild))
}) })

View file

@ -5,15 +5,53 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// InhumePrm encapsulates parameters for Inhume operation.
type InhumePrm struct {
target, tomb *objectSDK.Address
}
// InhumeRes encapsulates results of Inhume operation.
type InhumeRes struct{}
// WithAddress sets object address that should be inhumed.
func (p *InhumePrm) WithAddress(addr *objectSDK.Address) *InhumePrm {
if p != nil {
p.target = addr
}
return p
}
// WithTombstoneAddress sets tombstone address as the reason for inhume operation.
func (p *InhumePrm) WithTombstoneAddress(addr *objectSDK.Address) *InhumePrm {
if p != nil {
p.tomb = addr
}
return p
}
// Inhume inhumes the object by specified address.
func Inhume(db *DB, target, tomb *objectSDK.Address) error {
_, err := db.Inhume(new(InhumePrm).
WithAddress(target).
WithTombstoneAddress(tomb),
)
return err
}
// Inhume marks objects as removed but not removes it from metabase. // Inhume marks objects as removed but not removes it from metabase.
func (db *DB) Inhume(target, tombstone *objectSDK.Address) error { func (db *DB) Inhume(prm *InhumePrm) (res *InhumeRes, err error) {
return db.boltDB.Update(func(tx *bbolt.Tx) error { err = db.boltDB.Update(func(tx *bbolt.Tx) error {
graveyard, err := tx.CreateBucketIfNotExists(graveyardBucketName) graveyard, err := tx.CreateBucketIfNotExists(graveyardBucketName)
if err != nil { if err != nil {
return err return err
} }
// consider checking if target is already in graveyard? // consider checking if target is already in graveyard?
return graveyard.Put(addressKey(target), addressKey(tombstone)) return graveyard.Put(addressKey(prm.target), addressKey(prm.tomb))
}) })
return
} }

View file

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -16,15 +17,15 @@ func TestDB_Inhume(t *testing.T) {
tombstoneID := generateAddress() tombstoneID := generateAddress()
err := db.Put(raw.Object(), nil) err := putBig(db, raw.Object())
require.NoError(t, err) require.NoError(t, err)
err = db.Inhume(raw.Object().Address(), tombstoneID) err = meta.Inhume(db, raw.Object().Address(), tombstoneID)
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exists(raw.Object().Address()) _, err = meta.Exists(db, raw.Object().Address())
require.EqualError(t, err, object.ErrAlreadyRemoved.Error()) require.EqualError(t, err, object.ErrAlreadyRemoved.Error())
_, err = db.Get(raw.Object().Address()) _, err = meta.Get(db, raw.Object().Address())
require.EqualError(t, err, object.ErrAlreadyRemoved.Error()) require.EqualError(t, err, object.ErrAlreadyRemoved.Error())
} }

View file

@ -7,33 +7,106 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// ToMoveItPrm groups the parameters of ToMoveIt operation.
type ToMoveItPrm struct {
addr *objectSDK.Address
}
// ToMoveItRes groups resulting values of ToMoveIt operation.
type ToMoveItRes struct{}
// WithAddress sets address of the object to move into another shard.
func (p *ToMoveItPrm) WithAddress(addr *objectSDK.Address) *ToMoveItPrm {
if p != nil {
p.addr = addr
}
return p
}
// DoNotMovePrm groups the parameters of DoNotMove operation.
type DoNotMovePrm struct {
addr *objectSDK.Address
}
// DoNotMoveRes groups resulting values of DoNotMove operation.
type DoNotMoveRes struct{}
// WithAddress sets address of the object to prevent moving into another shard.
func (p *DoNotMovePrm) WithAddress(addr *objectSDK.Address) *DoNotMovePrm {
if p != nil {
p.addr = addr
}
return p
}
// MovablePrm groups the parameters of Movable operation.
type MovablePrm struct{}
// MovableRes groups resulting values of Movable operation.
type MovableRes struct {
addrList []*objectSDK.Address
}
// WithAddress sets address of the object to prevent moving into another shard.
func (p *MovableRes) AddressList() []*objectSDK.Address {
return p.addrList
}
// ToMoveIt marks object to move it into another shard.
func ToMoveIt(db *DB, addr *objectSDK.Address) error {
_, err := db.ToMoveIt(new(ToMoveItPrm).WithAddress(addr))
return err
}
// ToMoveIt marks objects to move it into another shard. This useful for // ToMoveIt marks objects to move it into another shard. This useful for
// faster HRW fetching. // faster HRW fetching.
func (db *DB) ToMoveIt(addr *objectSDK.Address) error { func (db *DB) ToMoveIt(prm *ToMoveItPrm) (res *ToMoveItRes, err error) {
return db.boltDB.Update(func(tx *bbolt.Tx) error { err = db.boltDB.Update(func(tx *bbolt.Tx) error {
toMoveIt, err := tx.CreateBucketIfNotExists(toMoveItBucketName) toMoveIt, err := tx.CreateBucketIfNotExists(toMoveItBucketName)
if err != nil { if err != nil {
return err return err
} }
return toMoveIt.Put(addressKey(addr), zeroValue) return toMoveIt.Put(addressKey(prm.addr), zeroValue)
}) })
return
}
// DoNotMove prevents the object to be moved into another shard.
func DoNotMove(db *DB, addr *objectSDK.Address) error {
_, err := db.DoNotMove(new(DoNotMovePrm).WithAddress(addr))
return err
} }
// DoNotMove removes `MoveIt` mark from the object. // DoNotMove removes `MoveIt` mark from the object.
func (db *DB) DoNotMove(addr *objectSDK.Address) error { func (db *DB) DoNotMove(prm *DoNotMovePrm) (res *DoNotMoveRes, err error) {
return db.boltDB.Update(func(tx *bbolt.Tx) error { err = db.boltDB.Update(func(tx *bbolt.Tx) error {
toMoveIt := tx.Bucket(toMoveItBucketName) toMoveIt := tx.Bucket(toMoveItBucketName)
if toMoveIt == nil { if toMoveIt == nil {
return nil return nil
} }
return toMoveIt.Delete(addressKey(addr)) return toMoveIt.Delete(addressKey(prm.addr))
}) })
return
}
// Movable returns all movable objects of DB.
func Movable(db *DB) ([]*objectSDK.Address, error) {
r, err := db.Movable(new(MovablePrm))
if err != nil {
return nil, err
}
return r.AddressList(), nil
} }
// Movable returns list of marked objects to move into other shard. // Movable returns list of marked objects to move into other shard.
func (db *DB) Movable() ([]*objectSDK.Address, error) { func (db *DB) Movable(prm *MovablePrm) (*MovableRes, error) {
var strAddrs []string var strAddrs []string
err := db.boltDB.View(func(tx *bbolt.Tx) error { err := db.boltDB.View(func(tx *bbolt.Tx) error {
@ -69,5 +142,7 @@ func (db *DB) Movable() ([]*objectSDK.Address, error) {
addrs = append(addrs, addr) addrs = append(addrs, addr)
} }
return addrs, nil return &MovableRes{
addrList: addrs,
}, nil
} }

View file

@ -3,6 +3,7 @@ package meta_test
import ( import (
"testing" "testing"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -14,42 +15,42 @@ func TestDB_Movable(t *testing.T) {
raw2 := generateRawObject(t) raw2 := generateRawObject(t)
// put two objects in metabase // put two objects in metabase
err := db.Put(raw1.Object(), nil) err := putBig(db, raw1.Object())
require.NoError(t, err) require.NoError(t, err)
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
// check if toMoveIt index empty // check if toMoveIt index empty
toMoveList, err := db.Movable() toMoveList, err := meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, toMoveList, 0) require.Len(t, toMoveList, 0)
// mark to move object2 // mark to move object2
err = db.ToMoveIt(raw2.Object().Address()) err = meta.ToMoveIt(db, raw2.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// check if toMoveIt index contains address of object 2 // check if toMoveIt index contains address of object 2
toMoveList, err = db.Movable() toMoveList, err = meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, toMoveList, 1) require.Len(t, toMoveList, 1)
require.Contains(t, toMoveList, raw2.Object().Address()) require.Contains(t, toMoveList, raw2.Object().Address())
// remove from toMoveIt index non existing address // remove from toMoveIt index non existing address
err = db.DoNotMove(raw1.Object().Address()) err = meta.DoNotMove(db, raw1.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// check if toMoveIt index hasn't changed // check if toMoveIt index hasn't changed
toMoveList, err = db.Movable() toMoveList, err = meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, toMoveList, 1) require.Len(t, toMoveList, 1)
// remove from toMoveIt index existing address // remove from toMoveIt index existing address
err = db.DoNotMove(raw2.Object().Address()) err = meta.DoNotMove(db, raw2.Object().Address())
require.NoError(t, err) require.NoError(t, err)
// check if toMoveIt index is empty now // check if toMoveIt index is empty now
toMoveList, err = db.Movable() toMoveList, err = meta.Movable(db)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, toMoveList, 0) require.Len(t, toMoveList, 0)
} }

View file

@ -18,6 +18,34 @@ type (
} }
) )
// PutPrm groups the parameters of Put operation.
type PutPrm struct {
obj *object.Object
id *blobovnicza.ID
}
// PutRes groups resulting values of Put operation.
type PutRes struct{}
// WithObject is a Put option to set object to save.
func (p *PutPrm) WithObject(obj *object.Object) *PutPrm {
if p != nil {
p.obj = obj
}
return p
}
// WithBlobovniczaID is a Put option to set blobovnicza ID to save.
func (p *PutPrm) WithBlobovniczaID(id *blobovnicza.ID) *PutPrm {
if p != nil {
p.id = id
}
return p
}
var ( var (
ErrUnknownObjectType = errors.New("unknown object type") ErrUnknownObjectType = errors.New("unknown object type")
ErrIncorrectBlobovniczaUpdate = errors.New("updating blobovnicza id on object without it") ErrIncorrectBlobovniczaUpdate = errors.New("updating blobovnicza id on object without it")
@ -25,12 +53,24 @@ var (
ErrIncorrectRootObject = errors.New("invalid root object") ErrIncorrectRootObject = errors.New("invalid root object")
) )
// Put saves the object in DB.
func Put(db *DB, obj *object.Object, id *blobovnicza.ID) error {
_, err := db.Put(new(PutPrm).
WithObject(obj).
WithBlobovniczaID(id),
)
return err
}
// Put saves object header in metabase. Object payload expected to be cut. // Put saves object header in metabase. Object payload expected to be cut.
// Big objects have nil blobovniczaID. // Big objects have nil blobovniczaID.
func (db *DB) Put(obj *object.Object, id *blobovnicza.ID) error { func (db *DB) Put(prm *PutPrm) (res *PutRes, err error) {
return db.boltDB.Update(func(tx *bbolt.Tx) error { err = db.boltDB.Update(func(tx *bbolt.Tx) error {
return db.put(tx, obj, id, nil) return db.put(tx, prm.obj, prm.id, nil)
}) })
return
} }
func (db *DB) put(tx *bbolt.Tx, obj *object.Object, id *blobovnicza.ID, si *objectSDK.SplitInfo) error { func (db *DB) put(tx *bbolt.Tx, obj *object.Object, id *blobovnicza.ID, si *objectSDK.SplitInfo) error {

View file

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -15,34 +16,34 @@ func TestDB_PutBlobovnicaUpdate(t *testing.T) {
blobovniczaID := blobovnicza.ID{1, 2, 3, 4} blobovniczaID := blobovnicza.ID{1, 2, 3, 4}
// put one object with blobovniczaID // put one object with blobovniczaID
err := db.Put(raw1.Object(), &blobovniczaID) err := meta.Put(db, raw1.Object(), &blobovniczaID)
require.NoError(t, err) require.NoError(t, err)
fetchedBlobovniczaID, err := db.IsSmall(raw1.Object().Address()) fetchedBlobovniczaID, err := meta.IsSmall(db, raw1.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, &blobovniczaID, fetchedBlobovniczaID) require.Equal(t, &blobovniczaID, fetchedBlobovniczaID)
t.Run("update blobovniczaID", func(t *testing.T) { t.Run("update blobovniczaID", func(t *testing.T) {
newID := blobovnicza.ID{5, 6, 7, 8} newID := blobovnicza.ID{5, 6, 7, 8}
err := db.Put(raw1.Object(), &newID) err := meta.Put(db, raw1.Object(), &newID)
require.NoError(t, err) require.NoError(t, err)
fetchedBlobovniczaID, err := db.IsSmall(raw1.Object().Address()) fetchedBlobovniczaID, err := meta.IsSmall(db, raw1.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, &newID, fetchedBlobovniczaID) require.Equal(t, &newID, fetchedBlobovniczaID)
}) })
t.Run("update blobovniczaID on bad object", func(t *testing.T) { t.Run("update blobovniczaID on bad object", func(t *testing.T) {
raw2 := generateRawObject(t) raw2 := generateRawObject(t)
err := db.Put(raw2.Object(), nil) err := putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
fetchedBlobovniczaID, err := db.IsSmall(raw2.Object().Address()) fetchedBlobovniczaID, err := meta.IsSmall(db, raw2.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Nil(t, fetchedBlobovniczaID) require.Nil(t, fetchedBlobovniczaID)
err = db.Put(raw2.Object(), &blobovniczaID) err = meta.Put(db, raw2.Object(), &blobovniczaID)
require.Error(t, err) require.Error(t, err)
}) })
} }

View file

@ -24,12 +24,48 @@ type (
} }
) )
// SelectPrm groups the parameters of Select operation.
type SelectPrm struct {
filters object.SearchFilters
}
// SelectRes groups resulting values of Select operation.
type SelectRes struct {
addrList []*object.Address
}
// WithFilters is a Select option to set the object filters.
func (p *SelectPrm) WithFilters(fs object.SearchFilters) *SelectPrm {
if p != nil {
p.filters = fs
}
return p
}
// AddressList returns list of addresses of the selected objects.
func (r *SelectRes) AddressList() []*object.Address {
return r.addrList
}
var ErrContainerNotInQuery = errors.New("search query does not contain container id filter") var ErrContainerNotInQuery = errors.New("search query does not contain container id filter")
// Select selects the objects from DB with filtering.
func Select(db *DB, fs object.SearchFilters) ([]*object.Address, error) {
r, err := db.Select(new(SelectPrm).WithFilters(fs))
if err != nil {
return nil, err
}
return r.AddressList(), nil
}
// Select returns list of addresses of objects that match search filters. // Select returns list of addresses of objects that match search filters.
func (db *DB) Select(fs object.SearchFilters) (res []*object.Address, err error) { func (db *DB) Select(prm *SelectPrm) (res *SelectRes, err error) {
res = new(SelectRes)
err = db.boltDB.View(func(tx *bbolt.Tx) error { err = db.boltDB.View(func(tx *bbolt.Tx) error {
res, err = db.selectObjects(tx, fs) res.addrList, err = db.selectObjects(tx, prm.filters)
return err return err
}) })

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-api-go/pkg/container"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
v2object "github.com/nspcc-dev/neofs-api-go/v2/object" v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -21,20 +22,20 @@ func TestDB_SelectUserAttributes(t *testing.T) {
addAttribute(raw1, "foo", "bar") addAttribute(raw1, "foo", "bar")
addAttribute(raw1, "x", "y") addAttribute(raw1, "x", "y")
err := db.Put(raw1.Object(), nil) err := putBig(db, raw1.Object())
require.NoError(t, err) require.NoError(t, err)
raw2 := generateRawObjectWithCID(t, cid) raw2 := generateRawObjectWithCID(t, cid)
addAttribute(raw2, "foo", "bar") addAttribute(raw2, "foo", "bar")
addAttribute(raw2, "x", "z") addAttribute(raw2, "x", "z")
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
raw3 := generateRawObjectWithCID(t, cid) raw3 := generateRawObjectWithCID(t, cid)
addAttribute(raw3, "a", "b") addAttribute(raw3, "a", "b")
err = db.Put(raw3.Object(), nil) err = putBig(db, raw3.Object())
require.NoError(t, err) require.NoError(t, err)
fs := generateSearchFilter(cid) fs := generateSearchFilter(cid)
@ -73,22 +74,22 @@ func TestDB_SelectRootPhyParent(t *testing.T) {
// prepare // prepare
small := generateRawObjectWithCID(t, cid) small := generateRawObjectWithCID(t, cid)
err := db.Put(small.Object(), nil) err := putBig(db, small.Object())
require.NoError(t, err) require.NoError(t, err)
ts := generateRawObjectWithCID(t, cid) ts := generateRawObjectWithCID(t, cid)
ts.SetType(objectSDK.TypeTombstone) ts.SetType(objectSDK.TypeTombstone)
err = db.Put(ts.Object(), nil) err = putBig(db, ts.Object())
require.NoError(t, err) require.NoError(t, err)
sg := generateRawObjectWithCID(t, cid) sg := generateRawObjectWithCID(t, cid)
sg.SetType(objectSDK.TypeStorageGroup) sg.SetType(objectSDK.TypeStorageGroup)
err = db.Put(sg.Object(), nil) err = putBig(db, sg.Object())
require.NoError(t, err) require.NoError(t, err)
leftChild := generateRawObjectWithCID(t, cid) leftChild := generateRawObjectWithCID(t, cid)
leftChild.InitRelations() leftChild.InitRelations()
err = db.Put(leftChild.Object(), nil) err = putBig(db, leftChild.Object())
require.NoError(t, err) require.NoError(t, err)
parent := generateRawObjectWithCID(t, cid) parent := generateRawObjectWithCID(t, cid)
@ -96,7 +97,7 @@ func TestDB_SelectRootPhyParent(t *testing.T) {
rightChild := generateRawObjectWithCID(t, cid) rightChild := generateRawObjectWithCID(t, cid)
rightChild.SetParent(parent.Object().SDK()) rightChild.SetParent(parent.Object().SDK())
rightChild.SetParentID(parent.ID()) rightChild.SetParentID(parent.ID())
err = db.Put(rightChild.Object(), nil) err = putBig(db, rightChild.Object())
require.NoError(t, err) require.NoError(t, err)
link := generateRawObjectWithCID(t, cid) link := generateRawObjectWithCID(t, cid)
@ -104,7 +105,7 @@ func TestDB_SelectRootPhyParent(t *testing.T) {
link.SetParentID(parent.ID()) link.SetParentID(parent.ID())
link.SetChildren(leftChild.ID(), rightChild.ID()) link.SetChildren(leftChild.ID(), rightChild.ID())
err = db.Put(link.Object(), nil) err = putBig(db, link.Object())
require.NoError(t, err) require.NoError(t, err)
t.Run("root objects", func(t *testing.T) { t.Run("root objects", func(t *testing.T) {
@ -186,11 +187,11 @@ func TestDB_SelectInhume(t *testing.T) {
cid := testCID() cid := testCID()
raw1 := generateRawObjectWithCID(t, cid) raw1 := generateRawObjectWithCID(t, cid)
err := db.Put(raw1.Object(), nil) err := putBig(db, raw1.Object())
require.NoError(t, err) require.NoError(t, err)
raw2 := generateRawObjectWithCID(t, cid) raw2 := generateRawObjectWithCID(t, cid)
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
fs := generateSearchFilter(cid) fs := generateSearchFilter(cid)
@ -203,7 +204,7 @@ func TestDB_SelectInhume(t *testing.T) {
tombstone.SetContainerID(cid) tombstone.SetContainerID(cid)
tombstone.SetObjectID(testOID()) tombstone.SetObjectID(testOID())
err = db.Inhume(raw2.Object().Address(), tombstone) err = meta.Inhume(db, raw2.Object().Address(), tombstone)
require.NoError(t, err) require.NoError(t, err)
fs = generateSearchFilter(cid) fs = generateSearchFilter(cid)
@ -219,11 +220,11 @@ func TestDB_SelectPayloadHash(t *testing.T) {
cid := testCID() cid := testCID()
raw1 := generateRawObjectWithCID(t, cid) raw1 := generateRawObjectWithCID(t, cid)
err := db.Put(raw1.Object(), nil) err := putBig(db, raw1.Object())
require.NoError(t, err) require.NoError(t, err)
raw2 := generateRawObjectWithCID(t, cid) raw2 := generateRawObjectWithCID(t, cid)
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
fs := generateSearchFilter(cid) fs := generateSearchFilter(cid)
@ -251,14 +252,14 @@ func TestDB_SelectWithSlowFilters(t *testing.T) {
raw1.SetPayloadSize(10) raw1.SetPayloadSize(10)
raw1.SetCreationEpoch(11) raw1.SetCreationEpoch(11)
raw1.SetVersion(v20) raw1.SetVersion(v20)
err := db.Put(raw1.Object(), nil) err := putBig(db, raw1.Object())
require.NoError(t, err) require.NoError(t, err)
raw2 := generateRawObjectWithCID(t, cid) raw2 := generateRawObjectWithCID(t, cid)
raw2.SetPayloadSize(20) raw2.SetPayloadSize(20)
raw2.SetCreationEpoch(21) raw2.SetCreationEpoch(21)
raw2.SetVersion(v21) raw2.SetVersion(v21)
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
t.Run("object with TZHash", func(t *testing.T) { t.Run("object with TZHash", func(t *testing.T) {
@ -312,17 +313,17 @@ func TestDB_SelectObjectID(t *testing.T) {
regular.SetParentID(parent.ID()) regular.SetParentID(parent.ID())
regular.SetParent(parent.Object().SDK()) regular.SetParent(parent.Object().SDK())
err := db.Put(regular.Object(), nil) err := putBig(db, regular.Object())
require.NoError(t, err) require.NoError(t, err)
ts := generateRawObjectWithCID(t, cid) ts := generateRawObjectWithCID(t, cid)
ts.SetType(objectSDK.TypeTombstone) ts.SetType(objectSDK.TypeTombstone)
err = db.Put(ts.Object(), nil) err = putBig(db, ts.Object())
require.NoError(t, err) require.NoError(t, err)
sg := generateRawObjectWithCID(t, cid) sg := generateRawObjectWithCID(t, cid)
sg.SetType(objectSDK.TypeStorageGroup) sg.SetType(objectSDK.TypeStorageGroup)
err = db.Put(sg.Object(), nil) err = putBig(db, sg.Object())
require.NoError(t, err) require.NoError(t, err)
t.Run("not found objects", func(t *testing.T) { t.Run("not found objects", func(t *testing.T) {
@ -376,9 +377,9 @@ func TestDB_SelectSplitID(t *testing.T) {
child2.SetSplitID(split1) child2.SetSplitID(split1)
child3.SetSplitID(split2) child3.SetSplitID(split2)
require.NoError(t, db.Put(child1.Object(), nil)) require.NoError(t, putBig(db, child1.Object()))
require.NoError(t, db.Put(child2.Object(), nil)) require.NoError(t, putBig(db, child2.Object()))
require.NoError(t, db.Put(child3.Object(), nil)) require.NoError(t, putBig(db, child3.Object()))
t.Run("split id", func(t *testing.T) { t.Run("split id", func(t *testing.T) {
fs := generateSearchFilter(cid) fs := generateSearchFilter(cid)

View file

@ -6,18 +6,56 @@ import (
"go.etcd.io/bbolt" "go.etcd.io/bbolt"
) )
// IsSmallPrm groups the parameters of IsSmall operation.
type IsSmallPrm struct {
addr *objectSDK.Address
}
// IsSmallRes groups resulting values of IsSmall operation.
type IsSmallRes struct {
id *blobovnicza.ID
}
// WithAddress is a IsSmall option to set the object address to check.
func (p *IsSmallPrm) WithAddress(addr *objectSDK.Address) *IsSmallPrm {
if p != nil {
p.addr = addr
}
return p
}
// BlobovniczaID returns blobovnicza identifier.
func (r *IsSmallRes) BlobovniczaID() *blobovnicza.ID {
return r.id
}
// IsSmall wraps work with DB.IsSmall method with specified
// address and other parameters by default. Returns only
// the blobovnicza identifier.
func IsSmall(db *DB, addr *objectSDK.Address) (*blobovnicza.ID, error) {
r, err := db.IsSmall(new(IsSmallPrm).WithAddress(addr))
if err != nil {
return nil, err
}
return r.BlobovniczaID(), nil
}
// IsSmall returns blobovniczaID for small objects and nil for big objects. // IsSmall returns blobovniczaID for small objects and nil for big objects.
// Small objects stored in blobovnicza instances. Big objects stored in FS by // Small objects stored in blobovnicza instances. Big objects stored in FS by
// shallow path which is calculated from address and therefore it is not // shallow path which is calculated from address and therefore it is not
// indexed in metabase. // indexed in metabase.
func (db *DB) IsSmall(addr *objectSDK.Address) (id *blobovnicza.ID, err error) { func (db *DB) IsSmall(prm *IsSmallPrm) (res *IsSmallRes, err error) {
res = new(IsSmallRes)
err = db.boltDB.View(func(tx *bbolt.Tx) error { err = db.boltDB.View(func(tx *bbolt.Tx) error {
id, err = db.isSmall(tx, addr) res.id, err = db.isSmall(tx, prm.addr)
return err return err
}) })
return id, err return
} }
func (db *DB) isSmall(tx *bbolt.Tx, addr *objectSDK.Address) (*blobovnicza.ID, error) { func (db *DB) isSmall(tx *bbolt.Tx, addr *objectSDK.Address) (*blobovnicza.ID, error) {

View file

@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -17,25 +18,25 @@ func TestDB_IsSmall(t *testing.T) {
blobovniczaID := blobovnicza.ID{1, 2, 3, 4} blobovniczaID := blobovnicza.ID{1, 2, 3, 4}
// check IsSmall from empty database // check IsSmall from empty database
fetchedBlobovniczaID, err := db.IsSmall(raw1.Object().Address()) fetchedBlobovniczaID, err := meta.IsSmall(db, raw1.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Nil(t, fetchedBlobovniczaID) require.Nil(t, fetchedBlobovniczaID)
// put one object with blobovniczaID // put one object with blobovniczaID
err = db.Put(raw1.Object(), &blobovniczaID) err = meta.Put(db, raw1.Object(), &blobovniczaID)
require.NoError(t, err) require.NoError(t, err)
// put one object without blobovniczaID // put one object without blobovniczaID
err = db.Put(raw2.Object(), nil) err = putBig(db, raw2.Object())
require.NoError(t, err) require.NoError(t, err)
// check IsSmall for object without blobovniczaID // check IsSmall for object without blobovniczaID
fetchedBlobovniczaID, err = db.IsSmall(raw2.Object().Address()) fetchedBlobovniczaID, err = meta.IsSmall(db, raw2.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Nil(t, fetchedBlobovniczaID) require.Nil(t, fetchedBlobovniczaID)
// check IsSmall for object with blobovniczaID // check IsSmall for object with blobovniczaID
fetchedBlobovniczaID, err = db.IsSmall(raw1.Object().Address()) fetchedBlobovniczaID, err = meta.IsSmall(db, raw1.Object().Address())
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, &blobovniczaID, fetchedBlobovniczaID) require.Equal(t, &blobovniczaID, fetchedBlobovniczaID)
} }

View file

@ -4,6 +4,7 @@ import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -46,7 +47,7 @@ func (s *Shard) Delete(prm *DeletePrm) (*DeleteRes, error) {
} }
} }
blobovniczaID, err := s.metaBase.IsSmall(prm.addr[i]) blobovniczaID, err := meta.IsSmall(s.metaBase, prm.addr[i])
if err != nil { if err != nil {
s.log.Debug("can't get blobovniczaID from metabase", s.log.Debug("can't get blobovniczaID from metabase",
zap.Stringer("object", prm.addr[i]), zap.Stringer("object", prm.addr[i]),
@ -60,7 +61,7 @@ func (s *Shard) Delete(prm *DeletePrm) (*DeleteRes, error) {
} }
} }
err := s.metaBase.Delete(prm.addr...) err := meta.Delete(s.metaBase, prm.addr...)
if err != nil { if err != nil {
return nil, err // stop on metabase error ? return nil, err // stop on metabase error ?
} }

View file

@ -2,6 +2,7 @@ package shard
import ( import (
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
) )
// ExistsPrm groups the parameters of Exists operation. // ExistsPrm groups the parameters of Exists operation.
@ -41,5 +42,5 @@ func (s *Shard) Exists(prm *ExistsPrm) (*ExistsRes, error) {
} }
func (s *Shard) objectExists(addr *object.Address) (bool, error) { func (s *Shard) objectExists(addr *object.Address) (bool, error) {
return s.metaBase.Exists(addr) return meta.Exists(s.metaBase, addr)
} }

View file

@ -7,6 +7,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
) )
// storFetcher is a type to unify object fetching mechanism in `fetchObjectData` // storFetcher is a type to unify object fetching mechanism in `fetchObjectData`
@ -103,7 +104,7 @@ func (s *Shard) fetchObjectData(addr *objectSDK.Address, big, small storFetcher)
s.log.Debug("miss in writeCache shallow dir") s.log.Debug("miss in writeCache shallow dir")
} }
exists, err := s.metaBase.Exists(addr) exists, err := meta.Exists(s.metaBase, addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -112,7 +113,7 @@ func (s *Shard) fetchObjectData(addr *objectSDK.Address, big, small storFetcher)
return nil, object.ErrNotFound return nil, object.ErrNotFound
} }
blobovniczaID, err := s.metaBase.IsSmall(addr) blobovniczaID, err := meta.IsSmall(s.metaBase, addr)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't fetch blobovnicza id from metabase: %w", err) return nil, fmt.Errorf("can't fetch blobovnicza id from metabase: %w", err)
} }

View file

@ -3,6 +3,7 @@ package shard
import ( import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
) )
// HeadPrm groups the parameters of Head operation. // HeadPrm groups the parameters of Head operation.
@ -35,7 +36,7 @@ func (r *HeadRes) Object() *object.Object {
// //
// Returns any error encountered. // Returns any error encountered.
func (s *Shard) Head(prm *HeadPrm) (*HeadRes, error) { func (s *Shard) Head(prm *HeadPrm) (*HeadRes, error) {
head, err := s.metaBase.Get(prm.addr) head, err := meta.Get(s.metaBase, prm.addr)
return &HeadRes{ return &HeadRes{
obj: head, obj: head,

View file

@ -2,6 +2,7 @@ package shard
import ( import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -28,7 +29,7 @@ func (p *InhumePrm) WithTarget(addr, tombstone *objectSDK.Address) *InhumePrm {
// Inhume calls metabase. Inhume method to mark object as removed. It won't be // Inhume calls metabase. Inhume method to mark object as removed. It won't be
// removed physically from blobStor and metabase until `Delete` operation. // removed physically from blobStor and metabase until `Delete` operation.
func (s *Shard) Inhume(prm *InhumePrm) (*InhumeRes, error) { func (s *Shard) Inhume(prm *InhumePrm) (*InhumeRes, error) {
err := s.metaBase.Inhume(prm.target, prm.tombstone) err := meta.Inhume(s.metaBase, prm.target, prm.tombstone)
if err != nil { if err != nil {
s.log.Debug("could not mark object to delete in metabase", s.log.Debug("could not mark object to delete in metabase",
zap.String("error", err.Error()), zap.String("error", err.Error()),

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -20,7 +21,7 @@ func (s *Shard) List() (*SelectRes, error) {
filters = filters[:0] filters = filters[:0]
filters.AddObjectContainerIDFilter(object.MatchStringEqual, lst[i]) filters.AddObjectContainerIDFilter(object.MatchStringEqual, lst[i])
ids, err := s.metaBase.Select(filters) // consider making List in metabase ids, err := meta.Select(s.metaBase, filters) // consider making List in metabase
if err != nil { if err != nil {
s.log.Debug("can't select all objects", s.log.Debug("can't select all objects",
zap.Stringer("cid", lst[i]), zap.Stringer("cid", lst[i]),

View file

@ -2,6 +2,7 @@ package shard
import ( import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -26,7 +27,7 @@ func (p *ToMoveItPrm) WithAddress(addr *objectSDK.Address) *ToMoveItPrm {
// ToMoveIt calls metabase.ToMoveIt method to mark object as relocatable to // ToMoveIt calls metabase.ToMoveIt method to mark object as relocatable to
// another shard. // another shard.
func (s *Shard) ToMoveIt(prm *ToMoveItPrm) (*ToMoveItRes, error) { func (s *Shard) ToMoveIt(prm *ToMoveItPrm) (*ToMoveItRes, error) {
err := s.metaBase.ToMoveIt(prm.addr) err := meta.ToMoveIt(s.metaBase, prm.addr)
if err != nil { if err != nil {
s.log.Debug("could not mark object for shard relocation in metabase", s.log.Debug("could not mark object for shard relocation in metabase",
zap.String("error", err.Error()), zap.String("error", err.Error()),

View file

@ -3,6 +3,7 @@ package shard
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -56,7 +57,7 @@ func (s *Shard) Put(prm *PutPrm) (*PutRes, error) {
} }
// put to metabase // put to metabase
if err := s.metaBase.Put(prm.obj, res.BlobovniczaID()); err != nil { if err := meta.Put(s.metaBase, prm.obj, res.BlobovniczaID()); err != nil {
// may we need to handle this case in a special way // may we need to handle this case in a special way
// since the object has been successfully written to BlobStor // since the object has been successfully written to BlobStor
return nil, errors.Wrap(err, "could not put object to metabase") return nil, errors.Wrap(err, "could not put object to metabase")

View file

@ -2,6 +2,7 @@ package shard
import ( import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object" objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -34,7 +35,7 @@ func (r *SelectRes) AddressList() []*objectSDK.Address {
// Returns any error encountered that // Returns any error encountered that
// did not allow to completely select the objects. // did not allow to completely select the objects.
func (s *Shard) Select(prm *SelectPrm) (*SelectRes, error) { func (s *Shard) Select(prm *SelectPrm) (*SelectRes, error) {
addrList, err := s.metaBase.Select(prm.filters) addrList, err := meta.Select(s.metaBase, prm.filters)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not select objects from metabase") return nil, errors.Wrap(err, "could not select objects from metabase")
} }