diff --git a/cmd/neofs-lens/internal/meta/get.go b/cmd/neofs-lens/internal/meta/get.go index f7f3c194c1..5876bc24a5 100644 --- a/cmd/neofs-lens/internal/meta/get.go +++ b/cmd/neofs-lens/internal/meta/get.go @@ -5,7 +5,6 @@ import ( "fmt" common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-sdk-go/object" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" "github.com/spf13/cobra" @@ -38,27 +37,20 @@ func getFunc(cmd *cobra.Command, _ []string) error { } defer db.Close() - storageID := meta.StorageIDPrm{} - storageID.SetAddress(addr) - - resStorageID, err := db.StorageID(storageID) + id, err := db.StorageID(addr) if err != nil { return fmt.Errorf("could not check if the obj is small: %w", err) } - if id := resStorageID.StorageID(); id != nil { + if id != nil { cmd.Printf("Object storageID: %x (%q)\n\n", id, id) } else { cmd.Printf("Object does not contain storageID\n\n") } - prm := meta.GetPrm{} - prm.SetAddress(addr) - prm.SetRaw(true) - siErr := new(object.SplitInfoError) - res, err := db.Get(prm) + obj, err := db.Get(addr, true) if errors.As(err, &siErr) { link := siErr.SplitInfo().GetLink() last := siErr.SplitInfo().GetLastPart() @@ -79,7 +71,7 @@ func getFunc(cmd *cobra.Command, _ []string) error { return fmt.Errorf("could not get object: %w", err) } - common.PrintObjectHeader(cmd, *res.Header()) + common.PrintObjectHeader(cmd, *obj) return nil } diff --git a/cmd/neofs-lens/internal/meta/list-garbage.go b/cmd/neofs-lens/internal/meta/list-garbage.go index 915971fdb3..a47a40f79a 100644 --- a/cmd/neofs-lens/internal/meta/list-garbage.go +++ b/cmd/neofs-lens/internal/meta/list-garbage.go @@ -27,14 +27,10 @@ func listGarbageFunc(cmd *cobra.Command, _ []string) error { } defer db.Close() - var garbPrm meta.GarbageIterationPrm - garbPrm.SetHandler( - func(garbageObject meta.GarbageObject) error { - cmd.Println(garbageObject.Address().EncodeToString()) - return nil - }) - - err = db.IterateOverGarbage(garbPrm) + err = db.IterateOverGarbage(func(garbageObject meta.GarbageObject) error { + cmd.Println(garbageObject.Address().EncodeToString()) + return nil + }, nil) if err != nil { return fmt.Errorf("could not iterate over garbage bucket: %w", err) } diff --git a/cmd/neofs-lens/internal/meta/list-graveyard.go b/cmd/neofs-lens/internal/meta/list-graveyard.go index 8cf5528854..092a3f4241 100644 --- a/cmd/neofs-lens/internal/meta/list-graveyard.go +++ b/cmd/neofs-lens/internal/meta/list-graveyard.go @@ -27,20 +27,16 @@ func listGraveyardFunc(cmd *cobra.Command, _ []string) error { } defer db.Close() - var gravePrm meta.GraveyardIterationPrm - gravePrm.SetHandler( - func(tsObj meta.TombstonedObject) error { - cmd.Printf( - "Object: %s\nTS: %s (TS expiration: %d)\n", - tsObj.Address().EncodeToString(), - tsObj.Tombstone().EncodeToString(), - tsObj.TombstoneExpiration(), - ) - - return nil - }) - - err = db.IterateOverGraveyard(gravePrm) + err = db.IterateOverGraveyard(func(tsObj meta.TombstonedObject) error { + cmd.Printf( + "Object: %s\nTS: %s (TS expiration: %d)\n", + tsObj.Address().EncodeToString(), + tsObj.Tombstone().EncodeToString(), + tsObj.TombstoneExpiration(), + ) + + return nil + }, nil) if err != nil { return fmt.Errorf("could not iterate over graveyard bucket: %w", err) } diff --git a/cmd/neofs-lens/internal/meta/list.go b/cmd/neofs-lens/internal/meta/list.go index 82c6512290..115160a5c1 100644 --- a/cmd/neofs-lens/internal/meta/list.go +++ b/cmd/neofs-lens/internal/meta/list.go @@ -4,7 +4,6 @@ import ( "fmt" common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/spf13/cobra" ) @@ -40,15 +39,12 @@ func listFunc(cmd *cobra.Command, _ []string) error { return fmt.Errorf("%s flag must be positive", limitFlagName) } - var prm meta.ListPrm - prm.SetCount(vLimit) - - res, err := db.ListWithCursor(prm) + addrs, _, err := db.ListWithCursor(int(vLimit), nil) if err != nil { return fmt.Errorf("metabase's `ListWithCursor`: %w", err) } - for _, addressWithType := range res.AddressList() { + for _, addressWithType := range addrs { cmd.Printf("%s, Type: %s\n", addressWithType.Address, addressWithType.Type) } diff --git a/cmd/neofs-lens/internal/meta/put.go b/cmd/neofs-lens/internal/meta/put.go index 8bcabc08f0..b33b0db522 100644 --- a/cmd/neofs-lens/internal/meta/put.go +++ b/cmd/neofs-lens/internal/meta/put.go @@ -6,7 +6,6 @@ import ( "os" common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-sdk-go/object" "github.com/spf13/cobra" ) @@ -56,10 +55,7 @@ func writeObject(cmd *cobra.Command, _ []string) error { return errors.New("missing container ID in object") } - var pPrm meta.PutPrm - pPrm.SetObject(obj) - - _, err = db.Put(pPrm) + err = db.Put(obj, nil, nil) if err != nil { return fmt.Errorf("can't put object: %w", err) } diff --git a/cmd/neofs-lens/internal/storage/sanity.go b/cmd/neofs-lens/internal/storage/sanity.go index 7e47d4e88b..27e18aac17 100644 --- a/cmd/neofs-lens/internal/storage/sanity.go +++ b/cmd/neofs-lens/internal/storage/sanity.go @@ -156,12 +156,15 @@ func sanityCheck(cmd *cobra.Command, _ []string) error { } func checkShard(cmd *cobra.Command, sh storageShard) (int, error) { - var objectsChecked int - var mPrm meta.ListPrm - mPrm.SetCount(1024) + var ( + addrs []objectcore.AddressWithType + cursor *meta.Cursor + err error + objectsChecked int + ) for { - listRes, err := sh.m.ListWithCursor(mPrm) + addrs, cursor, err = sh.m.ListWithCursor(1024, cursor) if err != nil { if errors.Is(err, meta.ErrEndOfListing) { return objectsChecked, nil @@ -170,7 +173,7 @@ func checkShard(cmd *cobra.Command, sh storageShard) (int, error) { return objectsChecked, fmt.Errorf("listing objects in metabase: %w", err) } - for _, obj := range listRes.AddressList() { + for _, obj := range addrs { select { case <-cmd.Context().Done(): return objectsChecked, cmd.Context().Err() @@ -179,29 +182,21 @@ func checkShard(cmd *cobra.Command, sh storageShard) (int, error) { addr := obj.Address - var sIDPrm meta.StorageIDPrm - sIDPrm.SetAddress(addr) - - sIDRes, err := sh.m.StorageID(sIDPrm) + sid, err := sh.m.StorageID(addr) if err != nil { return objectsChecked, fmt.Errorf("reading %s storage ID in metabase: %w", addr, err) } - var mGet meta.GetPrm - mGet.SetAddress(addr) - - getRes, err := sh.m.Get(mGet) + header, err := sh.m.Get(addr, false) if err != nil { return objectsChecked, fmt.Errorf("reading %s object in metabase: %w", addr, err) } - header := *getRes.Header() - - switch id := string(sIDRes.StorageID()); id { + switch id := string(sid); id { case "": - err = checkObject(header, sh.fsT) + err = checkObject(*header, sh.fsT) case peapod.Type: - err = checkObject(header, sh.p) + err = checkObject(*header, sh.p) default: err = fmt.Errorf("uknown storage ID: %s", id) } @@ -217,8 +212,6 @@ func checkShard(cmd *cobra.Command, sh storageShard) (int, error) { objectsChecked++ } - - mPrm.SetCursor(listRes.Cursor()) } } diff --git a/pkg/local_object_storage/metabase/control_test.go b/pkg/local_object_storage/metabase/control_test.go index da6766693b..162f98f9bb 100644 --- a/pkg/local_object_storage/metabase/control_test.go +++ b/pkg/local_object_storage/metabase/control_test.go @@ -51,12 +51,5 @@ func TestReset(t *testing.T) { } func metaExists(db *meta.DB, addr oid.Address) (bool, error) { - var existsPrm meta.ExistsPrm - existsPrm.SetAddress(addr) - - res, err := db.Exists(existsPrm) - if err != nil { - return false, err - } - return res.Exists(), nil + return db.Exists(addr, false) } diff --git a/pkg/local_object_storage/metabase/counter_test.go b/pkg/local_object_storage/metabase/counter_test.go index 85d9273483..88401f00ee 100644 --- a/pkg/local_object_storage/metabase/counter_test.go +++ b/pkg/local_object_storage/metabase/counter_test.go @@ -32,12 +32,8 @@ func TestCounters(t *testing.T) { oo = append(oo, generateObject(t)) } - var prm meta.PutPrm - for i := range objCount { - prm.SetObject(oo[i]) - - _, err = db.Put(prm) + err = db.Put(oo[i], nil, nil) require.NoError(t, err) c, err = db.ObjectCounters() @@ -53,13 +49,10 @@ func TestCounters(t *testing.T) { t.Run("delete", func(t *testing.T) { oo := putObjs(t, db, objCount, false) - var prm meta.DeletePrm for i := objCount - 1; i >= 0; i-- { - prm.SetAddresses(objectcore.AddressOf(oo[i])) - - res, err := db.Delete(prm) + res, err := db.Delete([]oid.Address{objectcore.AddressOf(oo[i])}) require.NoError(t, err) - require.Equal(t, uint64(1), res.AvailableObjectsRemoved()) + require.Equal(t, uint64(1), res.AvailableRemoved) c, err = db.ObjectCounters() require.NoError(t, err) @@ -236,12 +229,9 @@ func TestCounters_Expired(t *testing.T) { // phy counter but does not affect the logic counter (after // that step they should be equal) - var deletePrm meta.DeletePrm - deletePrm.SetAddresses(oo[0]) - - deleteRes, err := db.Delete(deletePrm) + deleteRes, err := db.Delete(oo[:1]) require.NoError(t, err) - require.Zero(t, deleteRes.AvailableObjectsRemoved()) + require.Zero(t, deleteRes.AvailableRemoved) oo = oo[1:] @@ -254,11 +244,9 @@ func TestCounters_Expired(t *testing.T) { // service do) should decrease both counters despite the // expiration fact - deletePrm.SetAddresses(oo[0]) - - deleteRes, err = db.Delete(deletePrm) + deleteRes, err = db.Delete(oo[:1]) require.NoError(t, err) - require.Equal(t, uint64(1), deleteRes.AvailableObjectsRemoved()) + require.Equal(t, uint64(1), deleteRes.AvailableRemoved) oo = oo[1:] @@ -269,7 +257,6 @@ func TestCounters_Expired(t *testing.T) { } func putObjs(t *testing.T, db *meta.DB, count int, withParent bool) []*object.Object { - var prm meta.PutPrm var err error parent := generateObject(t) @@ -282,8 +269,7 @@ func putObjs(t *testing.T, db *meta.DB, count int, withParent bool) []*object.Ob oo = append(oo, o) - prm.SetObject(o) - _, err = db.Put(prm) + err = db.Put(o, nil, nil) require.NoError(t, err) c, err := db.ObjectCounters() diff --git a/pkg/local_object_storage/metabase/delete.go b/pkg/local_object_storage/metabase/delete.go index c069db89cb..8a7fa1a68c 100644 --- a/pkg/local_object_storage/metabase/delete.go +++ b/pkg/local_object_storage/metabase/delete.go @@ -14,50 +14,25 @@ import ( "go.uber.org/zap" ) -// DeletePrm groups the parameters of Delete operation. -type DeletePrm struct { - addrs []oid.Address -} - // DeleteRes groups the resulting values of Delete operation. type DeleteRes struct { - rawRemoved uint64 - availableRemoved uint64 - sizes []uint64 -} - -// AvailableObjectsRemoved returns the number of removed available -// objects. -func (d DeleteRes) AvailableObjectsRemoved() uint64 { - return d.availableRemoved -} - -// RawObjectsRemoved returns the number of removed raw objects. -func (d DeleteRes) RawObjectsRemoved() uint64 { - return d.rawRemoved -} - -// RemovedObjectSizes returns the sizes of removed objects. -// The order of the sizes is the same as in addresses' -// slice that was provided via [DeletePrm.SetAddresses], -// meaning that i-th size equals the number of freed up bytes -// after removing an object by i-th address. A zero size is -// allowed, it claims a missing object. -func (d DeleteRes) RemovedObjectSizes() []uint64 { - return d.sizes -} - -// SetAddresses is a Delete option to set the addresses of the objects to delete. -// -// Option is required. -func (p *DeletePrm) SetAddresses(addrs ...oid.Address) { - p.addrs = addrs + // RawRemoved contains the number of removed raw objects. + RawRemoved uint64 + // AvailableRemoved contains the number of removed available objects. + AvailableRemoved uint64 + // Sizes contains the sizes of removed objects. + // The order of the sizes is the same as in addresses' + // slice that was provided in the [DB.Delete] address list, + // meaning that i-th size equals the number of freed up bytes + // after removing an object by i-th address. A zero size is + // allowed, it claims a missing object. + Sizes []uint64 } -// Delete removed object records from metabase indexes. +// Delete removes object records from metabase indexes. // Does not stop on an error if there are more objects to handle requested; // returns the first error appeared with a number of deleted objects wrapped. -func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) { +func (db *DB) Delete(addrs []oid.Address) (DeleteRes, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() @@ -70,24 +45,24 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) { var rawRemoved uint64 var availableRemoved uint64 var err error - var sizes = make([]uint64, len(prm.addrs)) + var sizes = make([]uint64, len(addrs)) err = db.boltDB.Update(func(tx *bbolt.Tx) error { // We need to clear slice because tx can try to execute multiple times. - rawRemoved, availableRemoved, err = db.deleteGroup(tx, prm.addrs, sizes) + rawRemoved, availableRemoved, err = db.deleteGroup(tx, addrs, sizes) return err }) if err == nil { - for i := range prm.addrs { + for i := range addrs { storagelog.Write(db.log, - storagelog.AddressField(prm.addrs[i]), + storagelog.AddressField(addrs[i]), storagelog.OpField("metabase DELETE")) } } return DeleteRes{ - rawRemoved: rawRemoved, - availableRemoved: availableRemoved, - sizes: sizes, + RawRemoved: rawRemoved, + AvailableRemoved: availableRemoved, + Sizes: sizes, }, err } diff --git a/pkg/local_object_storage/metabase/delete_test.go b/pkg/local_object_storage/metabase/delete_test.go index 8159a466f5..08c965f477 100644 --- a/pkg/local_object_storage/metabase/delete_test.go +++ b/pkg/local_object_storage/metabase/delete_test.go @@ -132,9 +132,6 @@ func TestExpiredObject(t *testing.T) { } func metaDelete(db *meta.DB, addrs ...oid.Address) error { - var deletePrm meta.DeletePrm - deletePrm.SetAddresses(addrs...) - - _, err := db.Delete(deletePrm) + _, err := db.Delete(addrs) return err } diff --git a/pkg/local_object_storage/metabase/exists.go b/pkg/local_object_storage/metabase/exists.go index adf8957084..41dee81ef5 100644 --- a/pkg/local_object_storage/metabase/exists.go +++ b/pkg/local_object_storage/metabase/exists.go @@ -12,59 +12,37 @@ import ( "go.etcd.io/bbolt" ) -// ExistsPrm groups the parameters of Exists operation. -type ExistsPrm struct { - addr oid.Address - ignoreExpiration bool -} - -// ExistsRes groups the resulting values of Exists operation. -type ExistsRes struct { - exists bool -} - var ErrLackSplitInfo = logicerr.New("no split info on parent object") -// SetAddress is an Exists option to set object checked for existence. -func (p *ExistsPrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// IgnoreExpiration returns existence status despite the expiration status. -func (p *ExistsPrm) IgnoreExpiration() { - p.ignoreExpiration = true -} - -// Exists returns the fact that the object is in the metabase. -func (p ExistsRes) Exists() bool { - return p.exists -} - // 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 an error of type apistatus.ObjectAlreadyRemoved if object has been placed in graveyard. // Returns the object.ErrObjectIsExpired if the object is presented but already expired. -func (db *DB) Exists(prm ExistsPrm) (res ExistsRes, err error) { +func (db *DB) Exists(addr oid.Address, ignoreExpiration bool) (bool, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return false, ErrDegradedMode } - var currEpoch uint64 - if !prm.ignoreExpiration { + var ( + currEpoch uint64 + err error + exists bool + ) + if !ignoreExpiration { currEpoch = db.epochState.CurrentEpoch() } err = db.boltDB.View(func(tx *bbolt.Tx) error { - res.exists, err = db.exists(tx, prm.addr, currEpoch) + exists, err = db.exists(tx, addr, currEpoch) return err }) - return + return exists, err } func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists bool, err error) { diff --git a/pkg/local_object_storage/metabase/get.go b/pkg/local_object_storage/metabase/get.go index 11f2820361..ea12029038 100644 --- a/pkg/local_object_storage/metabase/get.go +++ b/pkg/local_object_storage/metabase/get.go @@ -14,59 +14,36 @@ import ( "go.etcd.io/bbolt" ) -// GetPrm groups the parameters of Get operation. -type GetPrm struct { - addr oid.Address - raw bool -} - -// GetRes groups the resulting values of Get operation. -type GetRes struct { - hdr *objectSDK.Object -} - -// SetAddress is a Get option to set the address of the requested object. -// -// Option is required. -func (p *GetPrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// SetRaw is a Get option to set raw flag value. If flag is unset, then Get -// returns header of virtual object, otherwise it returns SplitInfo of virtual -// object. -func (p *GetPrm) SetRaw(raw bool) { - p.raw = raw -} - -// Header returns the requested object header. -func (r GetRes) Header() *objectSDK.Object { - return r.hdr -} - // Get returns object header for specified address. // +// "raw" flag controls virtual object processing, when false (default) a +// proper object header is returned, when true only SplitInfo of virtual +// object is returned. +// // Returns an error of type apistatus.ObjectNotFound if object is missing in DB. // Returns an error of type apistatus.ObjectAlreadyRemoved if object has been placed in graveyard. // Returns the object.ErrObjectIsExpired if the object is presented but already expired. -func (db *DB) Get(prm GetPrm) (res GetRes, err error) { +func (db *DB) Get(addr oid.Address, raw bool) (*objectSDK.Object, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return nil, ErrDegradedMode } - - currEpoch := db.epochState.CurrentEpoch() + var ( + err error + hdr *objectSDK.Object + currEpoch = db.epochState.CurrentEpoch() + ) err = db.boltDB.View(func(tx *bbolt.Tx) error { key := make([]byte, addressKeySize) - res.hdr, err = db.get(tx, prm.addr, key, true, prm.raw, currEpoch) + hdr, err = db.get(tx, addr, key, true, raw, currEpoch) return err }) - return + return hdr, err } func (db *DB) get(tx *bbolt.Tx, addr oid.Address, key []byte, checkStatus, raw bool, currEpoch uint64) (*objectSDK.Object, error) { diff --git a/pkg/local_object_storage/metabase/get_test.go b/pkg/local_object_storage/metabase/get_test.go index 107cdf55b5..600bdadcfb 100644 --- a/pkg/local_object_storage/metabase/get_test.go +++ b/pkg/local_object_storage/metabase/get_test.go @@ -204,11 +204,9 @@ func benchmarkGet(b *testing.B, numOfObj int) { var counter int for pb.Next() { - var getPrm meta.GetPrm - getPrm.SetAddress(addrs[counter%len(addrs)]) counter++ - _, err := db.Get(getPrm) + _, err := db.Get(addrs[counter%len(addrs)], false) if err != nil { b.Fatal(err) } @@ -224,10 +222,7 @@ func benchmarkGet(b *testing.B, numOfObj int) { b.Run("serial", func(b *testing.B) { b.ReportAllocs() for i := range b.N { - var getPrm meta.GetPrm - getPrm.SetAddress(addrs[i%len(addrs)]) - - _, err := db.Get(getPrm) + _, err := db.Get(addrs[i%len(addrs)], false) if err != nil { b.Fatal(err) } @@ -283,13 +278,5 @@ func TestDB_GetContainer(t *testing.T) { } func metaGet(db *meta.DB, addr oid.Address, raw bool) (*objectSDK.Object, error) { - var prm meta.GetPrm - prm.SetAddress(addr) - prm.SetRaw(raw) - - res, err := db.Get(prm) - if err != nil { - return nil, err - } - return res.Header(), nil + return db.Get(addr, raw) } diff --git a/pkg/local_object_storage/metabase/graveyard.go b/pkg/local_object_storage/metabase/graveyard.go index 9b66b65aae..a2bd330ea9 100644 --- a/pkg/local_object_storage/metabase/graveyard.go +++ b/pkg/local_object_storage/metabase/graveyard.go @@ -25,20 +25,8 @@ func (g GarbageObject) Address() oid.Address { // GarbageHandler is a GarbageObject handling function. type GarbageHandler func(GarbageObject) error -// GarbageIterationPrm groups parameters of the garbage -// iteration process. -type GarbageIterationPrm struct { - h GarbageHandler - offset *oid.Address -} - -// SetHandler sets a handler that will be called on every -// GarbageObject. -func (g *GarbageIterationPrm) SetHandler(h GarbageHandler) { - g.h = h -} - -// SetOffset sets an offset of the iteration operation. +// IterateOverGarbage iterates over all objects marked with GC mark. +// // The handler will be applied to the next after the // specified offset if any are left. // @@ -50,16 +38,10 @@ func (g *GarbageIterationPrm) SetHandler(h GarbageHandler) { // next element. // // Nil offset means start an integration from the beginning. -func (g *GarbageIterationPrm) SetOffset(offset oid.Address) { - g.offset = &offset -} - -// IterateOverGarbage iterates over all objects -// marked with GC mark. // // If h returns ErrInterruptIterator, nil returns immediately. // Returns other errors of h directly. -func (db *DB) IterateOverGarbage(p GarbageIterationPrm) error { +func (db *DB) IterateOverGarbage(h GarbageHandler, offset *oid.Address) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() @@ -68,7 +50,7 @@ func (db *DB) IterateOverGarbage(p GarbageIterationPrm) error { } return db.boltDB.View(func(tx *bbolt.Tx) error { - return db.iterateDeletedObj(tx, gcHandler{p.h}, p.offset) + return db.iterateDeletedObj(tx, gcHandler{h}, offset) }) } @@ -101,20 +83,8 @@ func (g TombstonedObject) TombstoneExpiration() uint64 { // TombstonedHandler is a TombstonedObject handling function. type TombstonedHandler func(object TombstonedObject) error -// GraveyardIterationPrm groups parameters of the graveyard -// iteration process. -type GraveyardIterationPrm struct { - h TombstonedHandler - offset *oid.Address -} - -// SetHandler sets a handler that will be called on every -// TombstonedObject. -func (g *GraveyardIterationPrm) SetHandler(h TombstonedHandler) { - g.h = h -} - -// SetOffset sets an offset of the iteration operation. +// IterateOverGraveyard iterates over all graves in DB. +// // The handler will be applied to the next after the // specified offset if any are left. // @@ -126,15 +96,10 @@ func (g *GraveyardIterationPrm) SetHandler(h TombstonedHandler) { // next element. // // Nil offset means start an integration from the beginning. -func (g *GraveyardIterationPrm) SetOffset(offset oid.Address) { - g.offset = &offset -} - -// IterateOverGraveyard iterates over all graves in DB. // // If h returns ErrInterruptIterator, nil returns immediately. // Returns other errors of h directly. -func (db *DB) IterateOverGraveyard(p GraveyardIterationPrm) error { +func (db *DB) IterateOverGraveyard(h TombstonedHandler, offset *oid.Address) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() @@ -143,7 +108,7 @@ func (db *DB) IterateOverGraveyard(p GraveyardIterationPrm) error { } return db.boltDB.View(func(tx *bbolt.Tx) error { - return db.iterateDeletedObj(tx, graveyardHandler{p.h}, p.offset) + return db.iterateDeletedObj(tx, graveyardHandler{h}, offset) }) } diff --git a/pkg/local_object_storage/metabase/graveyard_test.go b/pkg/local_object_storage/metabase/graveyard_test.go index 714d0a3082..05d4cae2c7 100644 --- a/pkg/local_object_storage/metabase/graveyard_test.go +++ b/pkg/local_object_storage/metabase/graveyard_test.go @@ -18,24 +18,18 @@ func TestDB_IterateDeletedObjects_EmptyDB(t *testing.T) { db := newDB(t) var counter int - var iterGravePRM meta.GraveyardIterationPrm - iterGravePRM.SetHandler(func(garbage meta.TombstonedObject) error { + err := db.IterateOverGraveyard(func(garbage meta.TombstonedObject) error { counter++ return nil - }) - - err := db.IterateOverGraveyard(iterGravePRM) + }, nil) require.NoError(t, err) require.Zero(t, counter) - var iterGCPRM meta.GarbageIterationPrm - iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error { + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { counter++ return nil - }) - - err = db.IterateOverGarbage(iterGCPRM) + }, nil) require.NoError(t, err) require.Zero(t, counter) } @@ -74,18 +68,17 @@ func TestDB_Iterate_OffsetNotFound(t *testing.T) { _, err = db.Inhume(inhumePrm) require.NoError(t, err) - var counter int + var ( + counter int + o2addr = object.AddressOf(obj2) + ) - var iterGCPRM meta.GarbageIterationPrm - iterGCPRM.SetOffset(object.AddressOf(obj2)) - iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error { + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { require.Equal(t, garbage.Address(), addr1) counter++ return nil - }) - - err = db.IterateOverGarbage(iterGCPRM) + }, &o2addr) require.NoError(t, err) // the second object would be put after the @@ -93,15 +86,12 @@ func TestDB_Iterate_OffsetNotFound(t *testing.T) { // will not receive the first object require.Equal(t, 0, counter) - iterGCPRM.SetOffset(addr3) - iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error { + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { require.Equal(t, garbage.Address(), addr1) counter++ return nil - }) - - err = db.IterateOverGarbage(iterGCPRM) + }, &addr3) require.NoError(t, err) // the third object would be put before the @@ -156,28 +146,22 @@ func TestDB_IterateDeletedObjects(t *testing.T) { buriedTS, buriedGC []oid.Address ) - var iterGravePRM meta.GraveyardIterationPrm - iterGravePRM.SetHandler(func(tomstoned meta.TombstonedObject) error { + err = db.IterateOverGraveyard(func(tomstoned meta.TombstonedObject) error { require.Equal(t, addrTombstone, tomstoned.Tombstone()) buriedTS = append(buriedTS, tomstoned.Address()) counterAll++ return nil - }) - - err = db.IterateOverGraveyard(iterGravePRM) + }, nil) require.NoError(t, err) - var iterGCPRM meta.GarbageIterationPrm - iterGCPRM.SetHandler(func(garbage meta.GarbageObject) error { + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { buriedGC = append(buriedGC, garbage.Address()) counterAll++ return nil - }) - - err = db.IterateOverGarbage(iterGCPRM) + }, nil) require.NoError(t, err) // objects covered with a tombstone @@ -243,8 +227,7 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) { gotGraveyard []oid.Address ) - var iterGraveyardPrm meta.GraveyardIterationPrm - iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error { + err = db.IterateOverGraveyard(func(tombstoned meta.TombstonedObject) error { require.Equal(t, addrTombstone, tombstoned.Tombstone()) gotGraveyard = append(gotGraveyard, tombstoned.Address()) @@ -255,26 +238,22 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) { } return nil - }) - - err = db.IterateOverGraveyard(iterGraveyardPrm) + }, nil) require.NoError(t, err) require.Equal(t, firstIterationSize, counter) require.Equal(t, firstIterationSize, len(gotGraveyard)) // last received address is an offset offset := gotGraveyard[len(gotGraveyard)-1] - iterGraveyardPrm.SetOffset(offset) - iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error { + + err = db.IterateOverGraveyard(func(tombstoned meta.TombstonedObject) error { require.Equal(t, addrTombstone, tombstoned.Tombstone()) gotGraveyard = append(gotGraveyard, tombstoned.Address()) counter++ return nil - }) - - err = db.IterateOverGraveyard(iterGraveyardPrm) + }, &offset) require.NoError(t, err) require.Equal(t, len(expectedGraveyard), counter) require.ElementsMatch(t, gotGraveyard, expectedGraveyard) @@ -282,14 +261,12 @@ func TestDB_IterateOverGraveyard_Offset(t *testing.T) { // last received object (last in db) as offset // should lead to no iteration at all offset = gotGraveyard[len(gotGraveyard)-1] - iterGraveyardPrm.SetOffset(offset) iWasCalled := false - iterGraveyardPrm.SetHandler(func(tombstoned meta.TombstonedObject) error { + + err = db.IterateOverGraveyard(func(tombstoned meta.TombstonedObject) error { iWasCalled = true return nil - }) - - err = db.IterateOverGraveyard(iterGraveyardPrm) + }, &offset) require.NoError(t, err) require.False(t, iWasCalled) } @@ -338,8 +315,7 @@ func TestDB_IterateOverGarbage_Offset(t *testing.T) { gotGarbage []oid.Address ) - var iterGarbagePrm meta.GarbageIterationPrm - iterGarbagePrm.SetHandler(func(garbage meta.GarbageObject) error { + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { gotGarbage = append(gotGarbage, garbage.Address()) counter++ @@ -348,24 +324,20 @@ func TestDB_IterateOverGarbage_Offset(t *testing.T) { } return nil - }) - - err = db.IterateOverGarbage(iterGarbagePrm) + }, nil) require.NoError(t, err) require.Equal(t, firstIterationSize, counter) require.Equal(t, firstIterationSize, len(gotGarbage)) // last received address is an offset offset := gotGarbage[len(gotGarbage)-1] - iterGarbagePrm.SetOffset(offset) - iterGarbagePrm.SetHandler(func(garbage meta.GarbageObject) error { + + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { gotGarbage = append(gotGarbage, garbage.Address()) counter++ return nil - }) - - err = db.IterateOverGarbage(iterGarbagePrm) + }, &offset) require.NoError(t, err) require.Equal(t, len(expectedGarbage), counter) require.ElementsMatch(t, gotGarbage, expectedGarbage) @@ -373,14 +345,12 @@ func TestDB_IterateOverGarbage_Offset(t *testing.T) { // last received object (last in db) as offset // should lead to no iteration at all offset = gotGarbage[len(gotGarbage)-1] - iterGarbagePrm.SetOffset(offset) iWasCalled := false - iterGarbagePrm.SetHandler(func(garbage meta.GarbageObject) error { + + err = db.IterateOverGarbage(func(garbage meta.GarbageObject) error { iWasCalled = true return nil - }) - - err = db.IterateOverGarbage(iterGarbagePrm) + }, &offset) require.NoError(t, err) require.False(t, iWasCalled) } @@ -448,9 +418,7 @@ func TestDropExpiredTSMarks(t *testing.T) { require.NoError(t, err) for _, o := range droppedObjects { - var pGet meta.GetPrm - pGet.SetAddress(o) - _, err = db.Get(pGet) + _, err = db.Get(o, false) require.ErrorIs(t, err, apistatus.ErrObjectAlreadyRemoved) } @@ -459,10 +427,7 @@ func TestDropExpiredTSMarks(t *testing.T) { require.EqualValues(t, len(droppedObjects)/2, res) // first half with epoch + 1 expiration for i, o := range droppedObjects { - var pGet meta.GetPrm - pGet.SetAddress(o) - - _, err = db.Get(pGet) + _, err = db.Get(o, false) if i < len(droppedObjects)/2 { require.ErrorIs(t, err, apistatus.ErrObjectNotFound) } else { @@ -475,9 +440,7 @@ func TestDropExpiredTSMarks(t *testing.T) { require.EqualValues(t, len(droppedObjects)/2, res) // second half with epoch + 2 expiration for _, o := range droppedObjects { - var pGet meta.GetPrm - pGet.SetAddress(o) - _, err = db.Get(pGet) + _, err = db.Get(o, false) require.ErrorIs(t, err, apistatus.ErrObjectNotFound) } } diff --git a/pkg/local_object_storage/metabase/inhume_test.go b/pkg/local_object_storage/metabase/inhume_test.go index 6c7f04da91..40eb80b970 100644 --- a/pkg/local_object_storage/metabase/inhume_test.go +++ b/pkg/local_object_storage/metabase/inhume_test.go @@ -45,7 +45,6 @@ func TestInhumeTombOnTomb(t *testing.T) { addr2 = oidtest.Address() addr3 = oidtest.Address() inhumePrm meta.InhumePrm - existsPrm meta.ExistsPrm ) inhumePrm.SetAddresses(addr1) @@ -55,10 +54,8 @@ func TestInhumeTombOnTomb(t *testing.T) { _, err = db.Inhume(inhumePrm) require.NoError(t, err) - existsPrm.SetAddress(addr1) - // addr1 should become inhumed {addr1:addr2} - _, err = db.Exists(existsPrm) + _, err = db.Exists(addr1, false) require.ErrorAs(t, err, new(apistatus.ObjectAlreadyRemoved)) inhumePrm.SetAddresses(addr3) @@ -72,13 +69,11 @@ func TestInhumeTombOnTomb(t *testing.T) { // as a tomb-on-tomb; metabase should return ObjectNotFound // NOT ObjectAlreadyRemoved since that record has been removed // from graveyard but addr1 is still marked with GC - _, err = db.Exists(existsPrm) + _, err = db.Exists(addr1, false) require.ErrorAs(t, err, new(apistatus.ObjectNotFound)) - existsPrm.SetAddress(addr3) - // addr3 should be inhumed {addr3: addr1} - _, err = db.Exists(existsPrm) + _, err = db.Exists(addr3, false) require.ErrorAs(t, err, new(apistatus.ObjectAlreadyRemoved)) inhumePrm.SetAddresses(addr1) @@ -88,12 +83,10 @@ func TestInhumeTombOnTomb(t *testing.T) { _, err = db.Inhume(inhumePrm) require.NoError(t, err) - existsPrm.SetAddress(addr1) - // record with addr1 key should not appear in graveyard // (tomb can not be inhumed) but should be kept as object // with GC mark - _, err = db.Exists(existsPrm) + _, err = db.Exists(addr1, false) require.ErrorAs(t, err, new(apistatus.ObjectNotFound)) } diff --git a/pkg/local_object_storage/metabase/list.go b/pkg/local_object_storage/metabase/list.go index dbe74b135e..ae88aee01a 100644 --- a/pkg/local_object_storage/metabase/list.go +++ b/pkg/local_object_storage/metabase/list.go @@ -22,62 +22,31 @@ type Cursor struct { inBucketOffset []byte } -// ListPrm contains parameters for ListWithCursor operation. -type ListPrm struct { - count int - cursor *Cursor -} - -// SetCount sets maximum amount of addresses that ListWithCursor should return. -func (l *ListPrm) SetCount(count uint32) { - l.count = int(count) -} - -// SetCursor sets cursor for ListWithCursor operation. For initial request -// ignore this param or use nil value. For consecutive requests, use value -// from ListRes. -func (l *ListPrm) SetCursor(cursor *Cursor) { - l.cursor = cursor -} - -// ListRes contains values returned from ListWithCursor operation. -type ListRes struct { - addrList []objectcore.AddressWithType - cursor *Cursor -} - -// AddressList returns addresses selected by ListWithCursor operation. -func (l ListRes) AddressList() []objectcore.AddressWithType { - return l.addrList -} - -// Cursor returns cursor for consecutive listing requests. -func (l ListRes) Cursor() *Cursor { - return l.cursor -} - // ListWithCursor lists physical objects available in metabase starting from // cursor. Includes objects of all types. Does not include inhumed objects. // Use cursor value from response for consecutive requests. // // Returns ErrEndOfListing if there are no more objects to return or count // parameter set to zero. -func (db *DB) ListWithCursor(prm ListPrm) (res ListRes, err error) { +func (db *DB) ListWithCursor(count int, cursor *Cursor) ([]objectcore.AddressWithType, *Cursor, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return nil, nil, ErrDegradedMode } - result := make([]objectcore.AddressWithType, 0, prm.count) + var ( + err error + result = make([]objectcore.AddressWithType, 0, count) + ) err = db.boltDB.View(func(tx *bbolt.Tx) error { - res.addrList, res.cursor, err = db.listWithCursor(tx, result, prm.count, prm.cursor) + result, cursor, err = db.listWithCursor(tx, result, count, cursor) return err }) - return res, err + return result, cursor, err } func (db *DB) listWithCursor(tx *bbolt.Tx, result []objectcore.AddressWithType, count int, cursor *Cursor) ([]objectcore.AddressWithType, *Cursor, error) { diff --git a/pkg/local_object_storage/metabase/list_test.go b/pkg/local_object_storage/metabase/list_test.go index f8853d34f6..5d6cb058e4 100644 --- a/pkg/local_object_storage/metabase/list_test.go +++ b/pkg/local_object_storage/metabase/list_test.go @@ -44,22 +44,23 @@ func listWithCursorPrepareDB(b *testing.B) *meta.DB { } func benchmarkListWithCursor(b *testing.B, db *meta.DB, batchSize int) { - var prm meta.ListPrm - prm.SetCount(uint32(batchSize)) + var ( + addrs []object.AddressWithType + cursor *meta.Cursor + err error + ) b.ResetTimer() b.ReportAllocs() for range b.N { - res, err := db.ListWithCursor(prm) + _, cursor, err = db.ListWithCursor(batchSize, cursor) if err != nil { if !errors.Is(err, meta.ErrEndOfListing) { b.Fatalf("error: %v", err) } - prm.SetCursor(nil) - } else if ln := len(res.AddressList()); ln != batchSize { + cursor = nil + } else if ln := len(addrs); ln != batchSize { b.Fatalf("invalid batch size: %d", ln) - } else { - prm.SetCursor(res.Cursor()) } } } @@ -222,13 +223,5 @@ func sortAddresses(addrWithType []object.AddressWithType) []object.AddressWithTy } func metaListWithCursor(db *meta.DB, count uint32, cursor *meta.Cursor) ([]object.AddressWithType, *meta.Cursor, error) { - var listPrm meta.ListPrm - listPrm.SetCount(count) - listPrm.SetCursor(cursor) - - r, err := db.ListWithCursor(listPrm) - if err != nil { - return nil, nil, err - } - return r.AddressList(), r.Cursor(), nil + return db.ListWithCursor(int(count), cursor) } diff --git a/pkg/local_object_storage/metabase/lock.go b/pkg/local_object_storage/metabase/lock.go index 63fa62d9dd..d49432a2f1 100644 --- a/pkg/local_object_storage/metabase/lock.go +++ b/pkg/local_object_storage/metabase/lock.go @@ -225,41 +225,22 @@ func freePotentialLocks(tx *bbolt.Tx, idCnr cid.ID, locker oid.ID) ([]oid.Addres return unlocked, nil } -// IsLockedPrm groups the parameters of IsLocked operation. -type IsLockedPrm struct { - addr oid.Address -} - -// SetAddress sets object address that will be checked for lock relations. -func (i *IsLockedPrm) SetAddress(addr oid.Address) { - i.addr = addr -} - -// IsLockedRes groups the resulting values of IsLocked operation. -type IsLockedRes struct { - locked bool -} - -// Locked describes the requested object status according to the metabase -// current state. -func (i IsLockedRes) Locked() bool { - return i.locked -} - // IsLocked checks is the provided object is locked by any `LOCK`. Not found // object is considered as non-locked. // // Returns only non-logical errors related to underlying database. -func (db *DB) IsLocked(prm IsLockedPrm) (res IsLockedRes, err error) { +func (db *DB) IsLocked(addr oid.Address) (bool, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return false, ErrDegradedMode } - return res, db.boltDB.View(func(tx *bbolt.Tx) error { - res.locked = objectLocked(tx, prm.addr.Container(), prm.addr.Object()) + var locked bool + + return locked, db.boltDB.View(func(tx *bbolt.Tx) error { + locked = objectLocked(tx, addr.Container(), addr.Object()) return nil }) } diff --git a/pkg/local_object_storage/metabase/lock_test.go b/pkg/local_object_storage/metabase/lock_test.go index 1cfbb24166..c02de0ca04 100644 --- a/pkg/local_object_storage/metabase/lock_test.go +++ b/pkg/local_object_storage/metabase/lock_test.go @@ -177,42 +177,32 @@ func TestDB_IsLocked(t *testing.T) { // existing and locked objs objs, _ := putAndLockObj(t, db, 5) - var prm meta.IsLockedPrm for _, obj := range objs { - prm.SetAddress(objectcore.AddressOf(obj)) - - res, err := db.IsLocked(prm) + locked, err := db.IsLocked(objectcore.AddressOf(obj)) require.NoError(t, err) - require.True(t, res.Locked()) + require.True(t, locked) } // some rand obj - prm.SetAddress(oidtest.Address()) - - res, err := db.IsLocked(prm) + locked, err := db.IsLocked(oidtest.Address()) require.NoError(t, err) - require.False(t, res.Locked()) + require.False(t, locked) // existing but not locked obj obj := objecttest.Object() - var putPrm meta.PutPrm - putPrm.SetObject(&obj) - - _, err = db.Put(putPrm) + err = db.Put(&obj, nil, nil) require.NoError(t, err) - prm.SetAddress(objectcore.AddressOf(&obj)) - - res, err = db.IsLocked(prm) + locked, err = db.IsLocked(objectcore.AddressOf(&obj)) require.NoError(t, err) - require.False(t, res.Locked()) + require.False(t, locked) } func TestDB_Lock_Expired(t *testing.T) { diff --git a/pkg/local_object_storage/metabase/movable.go b/pkg/local_object_storage/metabase/movable.go index 42e9689cbf..0f924e2b12 100644 --- a/pkg/local_object_storage/metabase/movable.go +++ b/pkg/local_object_storage/metabase/movable.go @@ -7,97 +7,54 @@ import ( "go.etcd.io/bbolt" ) -// ToMoveItPrm groups the parameters of ToMoveIt operation. -type ToMoveItPrm struct { - addr oid.Address -} - -// ToMoveItRes groups the resulting values of ToMoveIt operation. -type ToMoveItRes struct{} - -// SetAddress sets address of the object to move into another shard. -func (p *ToMoveItPrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// DoNotMovePrm groups the parameters of DoNotMove operation. -type DoNotMovePrm struct { - addr oid.Address -} - -// DoNotMoveRes groups the resulting values of DoNotMove operation. -type DoNotMoveRes struct{} - -// SetAddress sets address of the object to prevent moving into another shard. -func (p *DoNotMovePrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// MovablePrm groups the parameters of Movable operation. -type MovablePrm struct{} - -// MovableRes groups the resulting values of Movable operation. -type MovableRes struct { - addrList []oid.Address -} - -// AddressList returns resulting addresses of Movable operation. -func (p MovableRes) AddressList() []oid.Address { - return p.addrList -} - // ToMoveIt marks objects to move it into another shard. This useful for // faster HRW fetching. -func (db *DB) ToMoveIt(prm ToMoveItPrm) (res ToMoveItRes, err error) { +func (db *DB) ToMoveIt(addr oid.Address) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return ErrDegradedMode } else if db.mode.ReadOnly() { - return res, ErrReadOnlyMode + return ErrReadOnlyMode } key := make([]byte, addressKeySize) - key = addressKey(prm.addr, key) + key = addressKey(addr, key) - err = db.boltDB.Update(func(tx *bbolt.Tx) error { + return db.boltDB.Update(func(tx *bbolt.Tx) error { toMoveIt := tx.Bucket(toMoveItBucketName) return toMoveIt.Put(key, zeroValue) }) - - return } // DoNotMove removes `MoveIt` mark from the object. -func (db *DB) DoNotMove(prm DoNotMovePrm) (res DoNotMoveRes, err error) { +func (db *DB) DoNotMove(addr oid.Address) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return ErrDegradedMode } else if db.mode.ReadOnly() { - return res, ErrReadOnlyMode + return ErrReadOnlyMode } key := make([]byte, addressKeySize) - key = addressKey(prm.addr, key) + key = addressKey(addr, key) - err = db.boltDB.Update(func(tx *bbolt.Tx) error { + return db.boltDB.Update(func(tx *bbolt.Tx) error { toMoveIt := tx.Bucket(toMoveItBucketName) return toMoveIt.Delete(key) }) - - return } // Movable returns list of marked objects to move into other shard. -func (db *DB) Movable(_ MovablePrm) (MovableRes, error) { +func (db *DB) Movable() ([]oid.Address, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return MovableRes{}, ErrDegradedMode + return nil, ErrDegradedMode } var strAddrs []string @@ -111,7 +68,7 @@ func (db *DB) Movable(_ MovablePrm) (MovableRes, error) { }) }) if err != nil { - return MovableRes{}, err + return nil, err } // we can parse strings to structures in-place, but probably it seems @@ -122,12 +79,10 @@ func (db *DB) Movable(_ MovablePrm) (MovableRes, error) { for i := range strAddrs { err = decodeAddressFromKey(&addrs[i], []byte(strAddrs[i])) if err != nil { - return MovableRes{}, fmt.Errorf("can't parse object address %v: %w", + return nil, fmt.Errorf("can't parse object address %v: %w", strAddrs[i], err) } } - return MovableRes{ - addrList: addrs, - }, nil + return addrs, nil } diff --git a/pkg/local_object_storage/metabase/movable_test.go b/pkg/local_object_storage/metabase/movable_test.go index 560b7d4cda..d74a3daba5 100644 --- a/pkg/local_object_storage/metabase/movable_test.go +++ b/pkg/local_object_storage/metabase/movable_test.go @@ -57,26 +57,13 @@ func TestDB_Movable(t *testing.T) { } func metaToMoveIt(db *meta.DB, addr oid.Address) error { - var toMovePrm meta.ToMoveItPrm - toMovePrm.SetAddress(addr) - - _, err := db.ToMoveIt(toMovePrm) - return err + return db.ToMoveIt(addr) } func metaMovable(db *meta.DB) ([]oid.Address, error) { - r, err := db.Movable(meta.MovablePrm{}) - if err != nil { - return nil, err - } - - return r.AddressList(), nil + return db.Movable() } func metaDoNotMove(db *meta.DB, addr oid.Address) error { - var doNotMovePrm meta.DoNotMovePrm - doNotMovePrm.SetAddress(addr) - - _, err := db.DoNotMove(doNotMovePrm) - return err + return db.DoNotMove(addr) } diff --git a/pkg/local_object_storage/metabase/put.go b/pkg/local_object_storage/metabase/put.go index 9d8311ba2a..ccca03426a 100644 --- a/pkg/local_object_storage/metabase/put.go +++ b/pkg/local_object_storage/metabase/put.go @@ -21,68 +21,43 @@ type ( } ) -// PutPrm groups the parameters of Put operation. -type PutPrm struct { - obj *objectSDK.Object - - id []byte - - hdrBin []byte -} - -// PutRes groups the resulting values of Put operation. -type PutRes struct{} - -// SetObject is a Put option to set object to save. -func (p *PutPrm) SetObject(obj *objectSDK.Object) { - p.obj = obj -} - -// SetStorageID is a Put option to set storage ID to save. -func (p *PutPrm) SetStorageID(id []byte) { - p.id = id -} - -// SetHeaderBinary allows to provide the already encoded object header in [DB] -// format. If provided, the encoding step is skipped. It's the caller's -// responsibility to ensure that the data matches the object structure being -// processed. -func (p *PutPrm) SetHeaderBinary(hdrBin []byte) { - p.hdrBin = hdrBin -} - var ( ErrUnknownObjectType = errors.New("unknown object type") ErrIncorrectSplitInfoUpdate = errors.New("updating split info on object without it") ErrIncorrectRootObject = errors.New("invalid root object") ) -// Put saves object header in metabase. Object payload expected to be cut. +// Put saves object header in metabase. Object payload is expected to be cut. +// +// binHeader parameter is optional and allows to provide an already encoded +// object header in [DB] format. If provided, the encoding step is skipped. +// It's the caller's responsibility to ensure that the data matches the object +// structure being processed. // // Returns an error of type apistatus.ObjectAlreadyRemoved if object has been placed in graveyard. // Returns the object.ErrObjectIsExpired if the object is presented but already expired. -func (db *DB) Put(prm PutPrm) (res PutRes, err error) { +func (db *DB) Put(obj *objectSDK.Object, storageID []byte, binHeader []byte) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return ErrDegradedMode } else if db.mode.ReadOnly() { - return res, ErrReadOnlyMode + return ErrReadOnlyMode } currEpoch := db.epochState.CurrentEpoch() - err = db.boltDB.Batch(func(tx *bbolt.Tx) error { - return db.put(tx, prm.obj, prm.id, nil, currEpoch, prm.hdrBin) + err := db.boltDB.Batch(func(tx *bbolt.Tx) error { + return db.put(tx, obj, storageID, nil, currEpoch, binHeader) }) if err == nil { storagelog.Write(db.log, - storagelog.AddressField(objectCore.AddressOf(prm.obj)), + storagelog.AddressField(objectCore.AddressOf(obj)), storagelog.OpField("metabase PUT")) } - return + return err } func (db *DB) put( diff --git a/pkg/local_object_storage/metabase/put_test.go b/pkg/local_object_storage/metabase/put_test.go index 8fa9f52e37..dd4a256a60 100644 --- a/pkg/local_object_storage/metabase/put_test.go +++ b/pkg/local_object_storage/metabase/put_test.go @@ -115,13 +115,7 @@ func TestDB_PutBlobovnicaUpdate(t *testing.T) { } func metaPut(db *meta.DB, obj *objectSDK.Object, id []byte) error { - var putPrm meta.PutPrm - putPrm.SetObject(obj) - putPrm.SetStorageID(id) - - _, err := db.Put(putPrm) - - return err + return db.Put(obj, id, nil) } func TestDB_PutBinary(t *testing.T) { @@ -146,10 +140,7 @@ func TestDB_PutBinary(t *testing.T) { db := newDB(t) - var putPrm meta.PutPrm - putPrm.SetObject(hdr) - putPrm.SetHeaderBinary(hdrBin) - _, err := db.Put(putPrm) + err := db.Put(hdr, nil, hdrBin) require.NoError(t, err) res, err := metaGet(db, addr, false) @@ -159,9 +150,7 @@ func TestDB_PutBinary(t *testing.T) { // now place some garbage addr.SetObject(oidtest.ID()) hdr.SetID(addr.Object()) // to avoid 'already exists' outcome - putPrm.SetObject(hdr) - putPrm.SetHeaderBinary([]byte("definitely not an object")) - _, err = db.Put(putPrm) + err = db.Put(hdr, nil, []byte("definitely not an object")) require.NoError(t, err) _, err = metaGet(db, addr, false) diff --git a/pkg/local_object_storage/metabase/select.go b/pkg/local_object_storage/metabase/select.go index bc4403792b..c9fc2b8b14 100644 --- a/pkg/local_object_storage/metabase/select.go +++ b/pkg/local_object_storage/metabase/select.go @@ -31,32 +31,6 @@ type ( } ) -// SelectPrm groups the parameters of Select operation. -type SelectPrm struct { - cnr cid.ID - filters object.SearchFilters -} - -// SelectRes groups the resulting values of Select operation. -type SelectRes struct { - addrList []oid.Address -} - -// SetContainerID is a Select option to set the container id to search in. -func (p *SelectPrm) SetContainerID(cnr cid.ID) { - p.cnr = cnr -} - -// SetFilters is a Select option to set the object filters. -func (p *SelectPrm) SetFilters(fs object.SearchFilters) { - p.filters = fs -} - -// AddressList returns list of addresses of the selected objects. -func (r SelectRes) AddressList() []oid.Address { - return r.addrList -} - // Select returns list of addresses of objects that match search filters. // // Only creation epoch, payload size, user attributes and unknown system ones @@ -64,25 +38,30 @@ func (r SelectRes) AddressList() []oid.Address { // integers. // // Returns [object.ErrInvalidSearchQuery] if specified query is invalid. -func (db *DB) Select(prm SelectPrm) (res SelectRes, err error) { +func (db *DB) Select(cnr cid.ID, filters object.SearchFilters) ([]oid.Address, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return nil, ErrDegradedMode } - if blindlyProcess(prm.filters) { - return res, nil + if blindlyProcess(filters) { + return nil, nil } - currEpoch := db.epochState.CurrentEpoch() + var ( + addrList []oid.Address + currEpoch = db.epochState.CurrentEpoch() + err error + ) - return res, db.boltDB.View(func(tx *bbolt.Tx) error { - res.addrList, err = db.selectObjects(tx, prm.cnr, prm.filters, currEpoch) + err = db.boltDB.View(func(tx *bbolt.Tx) error { + addrList, err = db.selectObjects(tx, cnr, filters, currEpoch) return err }) + return addrList, err } func (db *DB) selectObjects(tx *bbolt.Tx, cnr cid.ID, fs object.SearchFilters, currEpoch uint64) ([]oid.Address, error) { diff --git a/pkg/local_object_storage/metabase/select_test.go b/pkg/local_object_storage/metabase/select_test.go index 6a3a694b0f..4a7bd7e413 100644 --- a/pkg/local_object_storage/metabase/select_test.go +++ b/pkg/local_object_storage/metabase/select_test.go @@ -874,31 +874,19 @@ func TestRemovedObjects(t *testing.T) { } func benchmarkSelect(b *testing.B, db *meta.DB, cid cidSDK.ID, fs objectSDK.SearchFilters, expected int) { - var prm meta.SelectPrm - prm.SetContainerID(cid) - prm.SetFilters(fs) - for range b.N { - res, err := db.Select(prm) + addrs, err := db.Select(cid, fs) if err != nil { b.Fatal(err) } - if len(res.AddressList()) != expected { - b.Fatalf("expected %d items, got %d", expected, len(res.AddressList())) + if len(addrs) != expected { + b.Fatalf("expected %d items, got %d", expected, len(addrs)) } } } func metaSelect(db *meta.DB, cnr cidSDK.ID, fs objectSDK.SearchFilters) ([]oid.Address, error) { - var prm meta.SelectPrm - prm.SetFilters(fs) - prm.SetContainerID(cnr) - - res, err := db.Select(prm) - if err != nil { - return nil, err - } - return res.AddressList(), nil + return db.Select(cnr, fs) } func numQuery(key string, op objectSDK.SearchMatchType, val string) (res objectSDK.SearchFilters) { diff --git a/pkg/local_object_storage/metabase/status.go b/pkg/local_object_storage/metabase/status.go index a764be692d..1caa5c6ec9 100644 --- a/pkg/local_object_storage/metabase/status.go +++ b/pkg/local_object_storage/metabase/status.go @@ -36,16 +36,14 @@ func (db *DB) ObjectStatus(address oid.Address) (ObjectStatus, error) { return res, nil } - storageID := StorageIDPrm{} - storageID.SetAddress(address) - resStorageID, err := db.StorageID(storageID) + resStorageID, err := db.StorageID(address) if err != nil { res.Error = fmt.Errorf("reading storage ID: %w", err) return res, res.Error } - if id := resStorageID.StorageID(); id != nil { - res.StorageID = string(id) + if resStorageID != nil { + res.StorageID = string(resStorageID) } err = db.boltDB.View(func(tx *bbolt.Tx) error { diff --git a/pkg/local_object_storage/metabase/storage_id.go b/pkg/local_object_storage/metabase/storage_id.go index 00a524eff9..492421ebb0 100644 --- a/pkg/local_object_storage/metabase/storage_id.go +++ b/pkg/local_object_storage/metabase/storage_id.go @@ -8,43 +8,28 @@ import ( "go.etcd.io/bbolt" ) -// StorageIDPrm groups the parameters of StorageID operation. -type StorageIDPrm struct { - addr oid.Address -} - -// StorageIDRes groups the resulting values of StorageID operation. -type StorageIDRes struct { - id []byte -} - -// SetAddress is a StorageID option to set the object address to check. -func (p *StorageIDPrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// StorageID returns storage ID. -func (r StorageIDRes) StorageID() []byte { - return r.id -} - // StorageID returns storage descriptor for objects from the blobstor. // It is put together with the object can makes get/delete operation faster. -func (db *DB) StorageID(prm StorageIDPrm) (res StorageIDRes, err error) { +func (db *DB) StorageID(addr oid.Address) ([]byte, error) { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return nil, ErrDegradedMode } + var ( + err error + id []byte + ) + err = db.boltDB.View(func(tx *bbolt.Tx) error { - res.id, err = db.storageID(tx, prm.addr) + id, err = db.storageID(tx, addr) return err }) - return + return id, err } func (db *DB) storageID(tx *bbolt.Tx, addr oid.Address) ([]byte, error) { @@ -62,46 +47,25 @@ func (db *DB) storageID(tx *bbolt.Tx, addr oid.Address) ([]byte, error) { return bytes.Clone(storageID), nil } -// UpdateStorageIDPrm groups the parameters of UpdateStorageID operation. -type UpdateStorageIDPrm struct { - addr oid.Address - id []byte -} - -// UpdateStorageIDRes groups the resulting values of UpdateStorageID operation. -type UpdateStorageIDRes struct{} - -// SetAddress is an UpdateStorageID option to set the object address to check. -func (p *UpdateStorageIDPrm) SetAddress(addr oid.Address) { - p.addr = addr -} - -// SetStorageID is an UpdateStorageID option to set the storage ID. -func (p *UpdateStorageIDPrm) SetStorageID(id []byte) { - p.id = id -} - // UpdateStorageID updates storage descriptor for objects from the blobstor. -func (db *DB) UpdateStorageID(prm UpdateStorageIDPrm) (res UpdateStorageIDRes, err error) { +func (db *DB) UpdateStorageID(addr oid.Address, newID []byte) error { db.modeMtx.RLock() defer db.modeMtx.RUnlock() if db.mode.NoMetabase() { - return res, ErrDegradedMode + return ErrDegradedMode } else if db.mode.ReadOnly() { - return res, ErrReadOnlyMode + return ErrReadOnlyMode } currEpoch := db.epochState.CurrentEpoch() - err = db.boltDB.Batch(func(tx *bbolt.Tx) error { - exists, err := db.exists(tx, prm.addr, currEpoch) + return db.boltDB.Batch(func(tx *bbolt.Tx) error { + exists, err := db.exists(tx, addr, currEpoch) if err == nil && exists || errors.Is(err, ErrObjectIsExpired) { - err = updateStorageID(tx, prm.addr, prm.id) + err = updateStorageID(tx, addr, newID) } return err }) - - return } diff --git a/pkg/local_object_storage/metabase/storage_id_test.go b/pkg/local_object_storage/metabase/storage_id_test.go index 13b76a6d18..1ead95a344 100644 --- a/pkg/local_object_storage/metabase/storage_id_test.go +++ b/pkg/local_object_storage/metabase/storage_id_test.go @@ -50,21 +50,9 @@ func TestDB_StorageID(t *testing.T) { } func metaUpdateStorageID(db *meta.DB, addr oid.Address, id []byte) error { - var sidPrm meta.UpdateStorageIDPrm - sidPrm.SetAddress(addr) - sidPrm.SetStorageID(id) - - _, err := db.UpdateStorageID(sidPrm) - return err + return db.UpdateStorageID(addr, id) } func metaStorageID(db *meta.DB, addr oid.Address) ([]byte, error) { - var sidPrm meta.StorageIDPrm - sidPrm.SetAddress(addr) - - r, err := db.StorageID(sidPrm) - if err != nil { - return nil, err - } - return r.StorageID(), nil + return db.StorageID(addr) } diff --git a/pkg/local_object_storage/shard/control.go b/pkg/local_object_storage/shard/control.go index 7650a8150b..7ed49ad649 100644 --- a/pkg/local_object_storage/shard/control.go +++ b/pkg/local_object_storage/shard/control.go @@ -241,11 +241,7 @@ func (s *Shard) resyncObjectHandler(addr oid.Address, data []byte, descriptor [] } } - var mPrm meta.PutPrm - mPrm.SetObject(obj) - mPrm.SetStorageID(descriptor) - - _, err := s.metaBase.Put(mPrm) + err := s.metaBase.Put(obj, descriptor, nil) if err != nil && !meta.IsErrRemoved(err) && !errors.Is(err, meta.ErrObjectIsExpired) { return err } diff --git a/pkg/local_object_storage/shard/delete.go b/pkg/local_object_storage/shard/delete.go index e8915c45aa..2aa0e9832f 100644 --- a/pkg/local_object_storage/shard/delete.go +++ b/pkg/local_object_storage/shard/delete.go @@ -4,7 +4,6 @@ import ( "errors" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" "go.uber.org/zap" @@ -60,10 +59,7 @@ func (s *Shard) delete(prm DeletePrm) (DeleteRes, error) { } } - var sPrm meta.StorageIDPrm - sPrm.SetAddress(prm.addr[i]) - - res, err := s.metaBase.StorageID(sPrm) + sid, err := s.metaBase.StorageID(prm.addr[i]) if err != nil { s.log.Debug("can't get storage ID from metabase", zap.Stringer("object", prm.addr[i]), @@ -72,27 +68,23 @@ func (s *Shard) delete(prm DeletePrm) (DeleteRes, error) { continue } - if res.StorageID() != nil { - smalls[prm.addr[i]] = res.StorageID() + if sid != nil { + smalls[prm.addr[i]] = sid } } - var delPrm meta.DeletePrm - delPrm.SetAddresses(prm.addr...) - - res, err := s.metaBase.Delete(delPrm) + res, err := s.metaBase.Delete(prm.addr) if err != nil { return DeleteRes{}, err // stop on metabase error ? } - s.decObjectCounterBy(physical, res.RawObjectsRemoved()) - s.decObjectCounterBy(logical, res.AvailableObjectsRemoved()) + s.decObjectCounterBy(physical, res.RawRemoved) + s.decObjectCounterBy(logical, res.AvailableRemoved) var totalRemovedPayload uint64 - removedSizes := res.RemovedObjectSizes() for i := range prm.addr { - removedPayload := removedSizes[i] + removedPayload := res.Sizes[i] totalRemovedPayload += removedPayload s.addToContainerSize(prm.addr[i].Container().EncodeToString(), -int64(removedPayload)) } diff --git a/pkg/local_object_storage/shard/exists.go b/pkg/local_object_storage/shard/exists.go index c359092b05..365fb7cc47 100644 --- a/pkg/local_object_storage/shard/exists.go +++ b/pkg/local_object_storage/shard/exists.go @@ -2,7 +2,6 @@ package shard import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" ) @@ -57,18 +56,10 @@ func (s *Shard) Exists(prm ExistsPrm) (ExistsRes, error) { } exists = res.Exists } else { - var existsPrm meta.ExistsPrm - existsPrm.SetAddress(prm.addr) - if prm.ignoreExpiration { - existsPrm.IgnoreExpiration() - } - - var res meta.ExistsRes - res, err = s.metaBase.Exists(existsPrm) + exists, err = s.metaBase.Exists(prm.addr, prm.ignoreExpiration) if err != nil { return ExistsRes{}, err } - exists = res.Exists() } return ExistsRes{ diff --git a/pkg/local_object_storage/shard/get.go b/pkg/local_object_storage/shard/get.go index 14aeb1d035..78fef02b5d 100644 --- a/pkg/local_object_storage/shard/get.go +++ b/pkg/local_object_storage/shard/get.go @@ -5,7 +5,6 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/util/logicerr" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/writecache" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" @@ -104,20 +103,15 @@ func (s *Shard) fetchObjectData(addr oid.Address, skipMeta bool, wc func(w writecache.Cache) error, ) (bool, error) { var ( - mErr error - mRes meta.ExistsRes + mErr error + exists bool ) - var exists bool if !skipMeta { - var mPrm meta.ExistsPrm - mPrm.SetAddress(addr) - - mRes, mErr = s.metaBase.Exists(mPrm) + exists, mErr = s.metaBase.Exists(addr, false) if mErr != nil && !s.info.Mode.NoMetabase() { return false, mErr } - exists = mRes.Exists() } if s.hasWriteCache() { @@ -147,15 +141,11 @@ func (s *Shard) fetchObjectData(addr oid.Address, skipMeta bool, return false, logicerr.Wrap(apistatus.ObjectNotFound{}) } - var mPrm meta.StorageIDPrm - mPrm.SetAddress(addr) - - mExRes, err := s.metaBase.StorageID(mPrm) + storageID, err := s.metaBase.StorageID(addr) if err != nil { return true, fmt.Errorf("can't fetch storage id from metabase: %w", err) } - storageID := mExRes.StorageID() if storageID == nil { // `nil` storageID returned without any error // means that object is big, `cb` expects an diff --git a/pkg/local_object_storage/shard/head.go b/pkg/local_object_storage/shard/head.go index 69bf5049b1..800e6a2e2b 100644 --- a/pkg/local_object_storage/shard/head.go +++ b/pkg/local_object_storage/shard/head.go @@ -1,7 +1,6 @@ package shard import ( - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" ) @@ -58,16 +57,10 @@ func (s *Shard) Head(prm HeadPrm) (HeadRes, error) { } obj = res.Object() } else { - var headParams meta.GetPrm - headParams.SetAddress(prm.addr) - headParams.SetRaw(prm.raw) - - var res meta.GetRes - res, err = s.metaBase.Get(headParams) + obj, err = s.metaBase.Get(prm.addr, prm.raw) if err != nil { return HeadRes{}, err } - obj = res.Header() } return HeadRes{ diff --git a/pkg/local_object_storage/shard/list.go b/pkg/local_object_storage/shard/list.go index e9afc251bf..b9af95e225 100644 --- a/pkg/local_object_storage/shard/list.go +++ b/pkg/local_object_storage/shard/list.go @@ -80,11 +80,7 @@ func (s *Shard) List() (res SelectRes, err error) { filters.AddPhyFilter() for i := range lst { - var sPrm meta.SelectPrm - sPrm.SetContainerID(lst[i]) - sPrm.SetFilters(filters) - - sRes, err := s.metaBase.Select(sPrm) // consider making List in metabase + addrs, err := s.metaBase.Select(lst[i], filters) // consider making List in metabase if err != nil { s.log.Debug("can't select all objects", zap.Stringer("cid", lst[i]), @@ -93,7 +89,7 @@ func (s *Shard) List() (res SelectRes, err error) { continue } - res.addrList = append(res.addrList, sRes.AddressList()...) + res.addrList = append(res.addrList, addrs...) } return res, nil @@ -125,16 +121,13 @@ func (s *Shard) ListWithCursor(prm ListWithCursorPrm) (ListWithCursorRes, error) return ListWithCursorRes{}, ErrDegradedMode } - var metaPrm meta.ListPrm - metaPrm.SetCount(prm.count) - metaPrm.SetCursor(prm.cursor) - res, err := s.metaBase.ListWithCursor(metaPrm) + addrs, cursor, err := s.metaBase.ListWithCursor(int(prm.count), prm.cursor) if err != nil { return ListWithCursorRes{}, fmt.Errorf("could not get list of objects: %w", err) } return ListWithCursorRes{ - addrList: res.AddressList(), - cursor: res.Cursor(), + addrList: addrs, + cursor: cursor, }, nil } diff --git a/pkg/local_object_storage/shard/lock.go b/pkg/local_object_storage/shard/lock.go index cd87c8dcfa..267987260f 100644 --- a/pkg/local_object_storage/shard/lock.go +++ b/pkg/local_object_storage/shard/lock.go @@ -3,7 +3,6 @@ package shard import ( "fmt" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" ) @@ -41,13 +40,5 @@ func (s *Shard) IsLocked(addr oid.Address) (bool, error) { return false, ErrDegradedMode } - var prm meta.IsLockedPrm - prm.SetAddress(addr) - - res, err := s.metaBase.IsLocked(prm) - if err != nil { - return false, err - } - - return res.Locked(), nil + return s.metaBase.IsLocked(addr) } diff --git a/pkg/local_object_storage/shard/move.go b/pkg/local_object_storage/shard/move.go index b585713a5b..381af30d59 100644 --- a/pkg/local_object_storage/shard/move.go +++ b/pkg/local_object_storage/shard/move.go @@ -1,7 +1,6 @@ package shard import ( - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" "go.uber.org/zap" ) @@ -33,10 +32,7 @@ func (s *Shard) ToMoveIt(prm ToMoveItPrm) (ToMoveItRes, error) { return ToMoveItRes{}, ErrDegradedMode } - var toMovePrm meta.ToMoveItPrm - toMovePrm.SetAddress(prm.addr) - - _, err := s.metaBase.ToMoveIt(toMovePrm) + err := s.metaBase.ToMoveIt(prm.addr) if err != nil { s.log.Debug("could not mark object for shard relocation in metabase", zap.String("error", err.Error()), diff --git a/pkg/local_object_storage/shard/put.go b/pkg/local_object_storage/shard/put.go index 2a79d95db1..d74a404b92 100644 --- a/pkg/local_object_storage/shard/put.go +++ b/pkg/local_object_storage/shard/put.go @@ -5,7 +5,6 @@ import ( objectCore "github.com/nspcc-dev/neofs-node/pkg/core/object" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-sdk-go/object" "go.uber.org/zap" ) @@ -89,13 +88,11 @@ func (s *Shard) Put(prm PutPrm) (PutRes, error) { } if !m.NoMetabase() { - var pPrm meta.PutPrm - pPrm.SetObject(prm.obj) + var binHeader []byte if prm.binSet { - pPrm.SetHeaderBinary(data[:prm.hdrLen]) + binHeader = data[:prm.hdrLen] } - pPrm.SetStorageID(res.StorageID) - if _, err := s.metaBase.Put(pPrm); err != nil { + if err := s.metaBase.Put(prm.obj, res.StorageID, binHeader); err != nil { // may we need to handle this case in a special way // since the object has been successfully written to BlobStor return PutRes{}, fmt.Errorf("could not put object to metabase: %w", err) diff --git a/pkg/local_object_storage/shard/select.go b/pkg/local_object_storage/shard/select.go index 95a29646f9..6d84070786 100644 --- a/pkg/local_object_storage/shard/select.go +++ b/pkg/local_object_storage/shard/select.go @@ -3,7 +3,6 @@ package shard import ( "fmt" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/object" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" @@ -49,16 +48,12 @@ func (s *Shard) Select(prm SelectPrm) (SelectRes, error) { return SelectRes{}, ErrDegradedMode } - var selectPrm meta.SelectPrm - selectPrm.SetFilters(prm.filters) - selectPrm.SetContainerID(prm.cnr) - - mRes, err := s.metaBase.Select(selectPrm) + addrs, err := s.metaBase.Select(prm.cnr, prm.filters) if err != nil { return SelectRes{}, fmt.Errorf("could not select objects from metabase: %w", err) } return SelectRes{ - addrList: mRes.AddressList(), + addrList: addrs, }, nil } diff --git a/pkg/local_object_storage/writecache/flush.go b/pkg/local_object_storage/writecache/flush.go index 0445e10dcb..68a8960f97 100644 --- a/pkg/local_object_storage/writecache/flush.go +++ b/pkg/local_object_storage/writecache/flush.go @@ -10,7 +10,6 @@ import ( objectCore "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/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" "github.com/nspcc-dev/neofs-sdk-go/object" oid "github.com/nspcc-dev/neofs-sdk-go/object/id" @@ -264,22 +263,13 @@ func (c *cache) flushObject(obj *object.Object, data []byte) error { return err } - var updPrm meta.UpdateStorageIDPrm - updPrm.SetAddress(addr) - updPrm.SetStorageID(res.StorageID) - - _, err = c.metabase.UpdateStorageID(updPrm) + err = c.metabase.UpdateStorageID(addr, res.StorageID) if err != nil { if errors.Is(err, apistatus.ErrObjectNotFound) { // we have the object and we just successfully put it so all the // information for restoring the object is here; meta can be // corrupted, resynced, etc, just trying our best - - var prmMeta meta.PutPrm - prmMeta.SetObject(obj) - prmMeta.SetStorageID(res.StorageID) - - _, err = c.metabase.Put(prmMeta) + err = c.metabase.Put(obj, res.StorageID, nil) if err != nil { err = fmt.Errorf("trying to restore missing object in metabase: %w", err) } diff --git a/pkg/local_object_storage/writecache/flush_test.go b/pkg/local_object_storage/writecache/flush_test.go index 475868a5c1..7c3550395e 100644 --- a/pkg/local_object_storage/writecache/flush_test.go +++ b/pkg/local_object_storage/writecache/flush_test.go @@ -55,15 +55,12 @@ func TestFlush(t *testing.T) { check := func(t *testing.T, mb *meta.DB, bs *blobstor.BlobStor, objects []objectPair) { for i := range objects { - var mPrm meta.StorageIDPrm - mPrm.SetAddress(objects[i].addr) - - mRes, err := mb.StorageID(mPrm) + id, err := mb.StorageID(objects[i].addr) require.NoError(t, err) var prm common.GetPrm prm.Address = objects[i].addr - prm.StorageID = mRes.StorageID() + prm.StorageID = id res, err := bs.Get(prm) require.NoError(t, err) @@ -85,9 +82,7 @@ func TestFlush(t *testing.T) { require.NoError(t, wc.Flush(false)) for i := range 2 { - var mPrm meta.GetPrm - mPrm.SetAddress(objects[i].addr) - _, err := mb.Get(mPrm) + _, err := mb.Get(objects[i].addr, false) require.Error(t, err) _, err = bs.Get(common.GetPrm{Address: objects[i].addr}) @@ -116,9 +111,7 @@ func TestFlush(t *testing.T) { require.NoError(t, wc.SetMode(mode.Degraded)) for i := range 2 { - var mPrm meta.GetPrm - mPrm.SetAddress(objects[i].addr) - _, err := mb.Get(mPrm) + _, err := mb.Get(objects[i].addr, false) require.Error(t, err) _, err = bs.Get(common.GetPrm{Address: objects[i].addr}) @@ -216,9 +209,7 @@ func TestFlush(t *testing.T) { require.NoError(t, mb.SetMode(mode.ReadWrite)) for i := range objects { - var prm meta.PutPrm - prm.SetObject(objects[i].obj) - _, err := mb.Put(prm) + err := mb.Put(objects[i].obj, nil, nil) require.NoError(t, err) } @@ -228,9 +219,7 @@ func TestFlush(t *testing.T) { _, err := mb.Inhume(inhumePrm) require.NoError(t, err) - var deletePrm meta.DeletePrm - deletePrm.SetAddresses(objects[2].addr, objects[3].addr) - _, err = mb.Delete(deletePrm) + _, err = mb.Delete([]oid.Address{objects[2].addr, objects[3].addr}) require.NoError(t, err) require.NoError(t, bs.SetMode(mode.ReadOnly)) diff --git a/pkg/local_object_storage/writecache/init.go b/pkg/local_object_storage/writecache/init.go index ac107dd16f..d9aa593918 100644 --- a/pkg/local_object_storage/writecache/init.go +++ b/pkg/local_object_storage/writecache/init.go @@ -105,19 +105,13 @@ func (c *cache) initFlushMarks() { // First return value is true iff object exists. // Second return value is true iff object can be safely removed. func (c *cache) flushStatus(addr oid.Address) (bool, bool) { - var existsPrm meta.ExistsPrm - existsPrm.SetAddress(addr) - - _, err := c.metabase.Exists(existsPrm) + _, err := c.metabase.Exists(addr, false) if err != nil { needRemove := errors.Is(err, meta.ErrObjectIsExpired) || errors.As(err, new(apistatus.ObjectAlreadyRemoved)) return needRemove, needRemove } - var prm meta.StorageIDPrm - prm.SetAddress(addr) - - mRes, _ := c.metabase.StorageID(prm) - res, err := c.blobstor.Exists(common.ExistsPrm{Address: addr, StorageID: mRes.StorageID()}) + sid, _ := c.metabase.StorageID(addr) + res, err := c.blobstor.Exists(common.ExistsPrm{Address: addr, StorageID: sid}) return err == nil && res.Exists, false } diff --git a/pkg/local_object_storage/writecache/options.go b/pkg/local_object_storage/writecache/options.go index 86215ddcb0..a7ce23e511 100644 --- a/pkg/local_object_storage/writecache/options.go +++ b/pkg/local_object_storage/writecache/options.go @@ -5,20 +5,20 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common" - meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" objectSDK "github.com/nspcc-dev/neofs-sdk-go/object" + oid "github.com/nspcc-dev/neofs-sdk-go/object/id" "go.uber.org/zap" ) // Option represents write-cache configuration option. type Option func(*options) -// meta is an interface for a metabase. -type metabase interface { - Exists(meta.ExistsPrm) (meta.ExistsRes, error) - StorageID(meta.StorageIDPrm) (meta.StorageIDRes, error) - UpdateStorageID(meta.UpdateStorageIDPrm) (meta.UpdateStorageIDRes, error) - Put(prm meta.PutPrm) (res meta.PutRes, err error) +// Metabase is an interface to metabase sufficient for writecache to operate. +type Metabase interface { + Exists(addr oid.Address, ignoreExpiration bool) (bool, error) + StorageID(addr oid.Address) ([]byte, error) + UpdateStorageID(addr oid.Address, newID []byte) error + Put(obj *objectSDK.Object, storageID []byte, binHeader []byte) error } // blob is an interface for the blobstor. @@ -35,7 +35,7 @@ type options struct { // blobstor is the main persistent storage. blobstor blob // metabase is the metabase instance. - metabase metabase + metabase Metabase // maxObjectSize is the maximum size of the object stored in the write-cache. maxObjectSize uint64 // smallObjectSize is the maximum size of the object stored in the database. @@ -79,7 +79,7 @@ func WithBlobstor(bs *blobstor.BlobStor) Option { } // WithMetabase sets metabase. -func WithMetabase(db *meta.DB) Option { +func WithMetabase(db Metabase) Option { return func(o *options) { o.metabase = db }