From 782005b9baf63590e81d2fb8521351f72fade04b Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 6 Nov 2024 19:14:36 +0300 Subject: [PATCH] metabase: drop almost all of Prm/Res structures They: * are present in some methods and not in others * add substantial cognitive overhead for anyone looking * require more code to handle trivial things * can allocate more and more of microobjects creating GC pressure Test wrappers in the same package perfectly suggest what everyone wanted to have in the first place. So this patch is a pure refactoring and doesn't change any behavior, but it drops almost all structures. "Almost" because there are cases where we pass a number of things (mostly as a result) and having some enclosing structure makes some sense there. Signed-off-by: Roman Khimov --- cmd/neofs-lens/internal/meta/get.go | 16 +-- cmd/neofs-lens/internal/meta/list-garbage.go | 12 +- .../internal/meta/list-graveyard.go | 24 ++-- cmd/neofs-lens/internal/meta/list.go | 8 +- cmd/neofs-lens/internal/meta/put.go | 6 +- cmd/neofs-lens/internal/storage/sanity.go | 33 +++--- .../metabase/control_test.go | 9 +- .../metabase/counter_test.go | 30 ++--- pkg/local_object_storage/metabase/delete.go | 65 ++++------- .../metabase/delete_test.go | 5 +- pkg/local_object_storage/metabase/exists.go | 42 ++----- pkg/local_object_storage/metabase/get.go | 49 +++----- pkg/local_object_storage/metabase/get_test.go | 19 +--- .../metabase/graveyard.go | 51 ++------- .../metabase/graveyard_test.go | 107 ++++++------------ .../metabase/inhume_test.go | 15 +-- pkg/local_object_storage/metabase/list.go | 47 ++------ .../metabase/list_test.go | 25 ++-- pkg/local_object_storage/metabase/lock.go | 31 +---- .../metabase/lock_test.go | 24 ++-- pkg/local_object_storage/metabase/movable.go | 75 +++--------- .../metabase/movable_test.go | 19 +--- pkg/local_object_storage/metabase/put.go | 51 +++------ pkg/local_object_storage/metabase/put_test.go | 17 +-- pkg/local_object_storage/metabase/select.go | 45 ++------ .../metabase/select_test.go | 20 +--- pkg/local_object_storage/metabase/status.go | 8 +- .../metabase/storage_id.go | 66 +++-------- .../metabase/storage_id_test.go | 16 +-- pkg/local_object_storage/shard/control.go | 6 +- pkg/local_object_storage/shard/delete.go | 22 ++-- pkg/local_object_storage/shard/exists.go | 11 +- pkg/local_object_storage/shard/get.go | 18 +-- pkg/local_object_storage/shard/head.go | 9 +- pkg/local_object_storage/shard/list.go | 17 +-- pkg/local_object_storage/shard/lock.go | 11 +- pkg/local_object_storage/shard/move.go | 6 +- pkg/local_object_storage/shard/put.go | 9 +- pkg/local_object_storage/shard/select.go | 9 +- pkg/local_object_storage/writecache/flush.go | 14 +-- .../writecache/flush_test.go | 23 +--- pkg/local_object_storage/writecache/init.go | 12 +- .../writecache/options.go | 18 +-- 43 files changed, 283 insertions(+), 837 deletions(-) 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 }