[#1523] shard: Store generic storage ID in metabase

Allow to extend blobstor with more storage sub-systems. Currently
objects stored in the FSTree have empty byte slice descriptor and object
from blobovnicza tree have the same id as earlier. Each such change in
the identifier formation should be accompanied with metabase version
increase.

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-07-06 17:09:50 +03:00 committed by fyrchik
parent 9eb018672c
commit 73f8bb3e5f
27 changed files with 220 additions and 251 deletions

View file

@ -204,7 +204,7 @@ func (b *Blobovniczas) Put(prm common.PutPrm) (common.PutRes, error) {
return common.PutRes{}, errPutFailed
}
return common.PutRes{BlobovniczaID: id}, nil
return common.PutRes{StorageID: id.Bytes()}, nil
}
// Get reads object from blobovnicza tree.
@ -215,8 +215,9 @@ func (b *Blobovniczas) Get(prm common.GetPrm) (res common.GetRes, err error) {
var bPrm blobovnicza.GetPrm
bPrm.SetAddress(prm.Address)
if prm.BlobovniczaID != nil {
blz, err := b.openBlobovnicza(prm.BlobovniczaID.String())
if prm.StorageID != nil {
id := blobovnicza.NewIDFromBytes(prm.StorageID)
blz, err := b.openBlobovnicza(id.String())
if err != nil {
return res, err
}
@ -265,8 +266,9 @@ func (b *Blobovniczas) Delete(prm common.DeletePrm) (res common.DeleteRes, err e
var bPrm blobovnicza.DeletePrm
bPrm.SetAddress(prm.Address)
if prm.BlobovniczaID != nil {
blz, err := b.openBlobovnicza(prm.BlobovniczaID.String())
if prm.StorageID != nil {
id := blobovnicza.NewIDFromBytes(prm.StorageID)
blz, err := b.openBlobovnicza(id.String())
if err != nil {
return res, err
}
@ -318,8 +320,9 @@ func (b *Blobovniczas) Delete(prm common.DeletePrm) (res common.DeleteRes, err e
// If blobocvnicza ID is specified, only this blobovnicza is processed.
// Otherwise, all Blobovniczas are processed descending weight.
func (b *Blobovniczas) GetRange(prm common.GetRangePrm) (res common.GetRangeRes, err error) {
if prm.BlobovniczaID != nil {
blz, err := b.openBlobovnicza(prm.BlobovniczaID.String())
if prm.StorageID != nil {
id := blobovnicza.NewIDFromBytes(prm.StorageID)
blz, err := b.openBlobovnicza(id.String())
if err != nil {
return common.GetRangeRes{}, err
}
@ -573,7 +576,7 @@ func (b *Blobovniczas) deleteObject(blz *blobovnicza.Blobovnicza, prm blobovnicz
storagelog.Write(b.log,
storagelog.AddressField(dp.Address),
storagelog.OpField("Blobovniczas DELETE"),
zap.Stringer("blobovnicza ID", dp.BlobovniczaID),
zap.Stringer("blobovnicza ID", blobovnicza.NewIDFromBytes(dp.StorageID)),
)
return common.DeleteRes{}, nil

View file

@ -78,7 +78,7 @@ func TestBlobovniczas(t *testing.T) {
// get w/ blobovnicza ID
var prm common.GetPrm
prm.BlobovniczaID = pRes.BlobovniczaID
prm.StorageID = pRes.StorageID
prm.Address = addr
res, err := b.Get(prm)
@ -86,7 +86,7 @@ func TestBlobovniczas(t *testing.T) {
require.Equal(t, obj, res.Object)
// get w/o blobovnicza ID
prm.BlobovniczaID = nil
prm.StorageID = nil
res, err = b.Get(prm)
require.NoError(t, err)
@ -94,7 +94,7 @@ func TestBlobovniczas(t *testing.T) {
// get range w/ blobovnicza ID
var rngPrm common.GetRangePrm
rngPrm.BlobovniczaID = pRes.BlobovniczaID
rngPrm.StorageID = pRes.StorageID
rngPrm.Address = addr
payload := obj.Payload()
@ -109,7 +109,7 @@ func TestBlobovniczas(t *testing.T) {
require.Equal(t, payload[off:off+ln], rngRes.Data)
// get range w/o blobovnicza ID
rngPrm.BlobovniczaID = nil
rngPrm.StorageID = nil
rngRes, err = b.GetRange(rngPrm)
require.NoError(t, err)

View file

@ -1,14 +1,13 @@
package common
import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
)
// DeletePrm groups the parameters of Delete operation.
type DeletePrm struct {
Address oid.Address
BlobovniczaID *blobovnicza.ID
Address oid.Address
StorageID []byte
}
// DeleteRes groups the resulting values of Delete operation.

View file

@ -1,14 +1,13 @@
package common
import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
)
type GetPrm struct {
Address oid.Address
BlobovniczaID *blobovnicza.ID
Address oid.Address
StorageID []byte
}
type GetRes struct {

View file

@ -1,15 +1,14 @@
package common
import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
)
type GetRangePrm struct {
Address oid.Address
Range objectSDK.Range
BlobovniczaID *blobovnicza.ID
Address oid.Address
Range objectSDK.Range
StorageID []byte
}
type GetRangeRes struct {

View file

@ -1,7 +1,6 @@
package common
import (
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
)
@ -15,5 +14,5 @@ type PutPrm struct {
// PutRes groups the resulting values of Put operation.
type PutRes struct {
BlobovniczaID *blobovnicza.ID
StorageID []byte
}

View file

@ -10,7 +10,7 @@ import (
)
func (b *BlobStor) Delete(prm common.DeletePrm) (common.DeleteRes, error) {
if prm.BlobovniczaID == nil {
if prm.StorageID == nil {
// Nothing specified, try everything.
res, err := b.deleteBig(prm)
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
@ -18,7 +18,7 @@ func (b *BlobStor) Delete(prm common.DeletePrm) (common.DeleteRes, error) {
}
return b.deleteSmall(prm)
}
if *prm.BlobovniczaID == nil {
if len(prm.StorageID) == 0 {
return b.deleteBig(prm)
}
return b.deleteSmall(prm)

View file

@ -14,7 +14,7 @@ import (
// If the descriptor is present, only one sub-storage is tried,
// Otherwise, each sub-storage is tried in order.
func (b *BlobStor) Get(prm common.GetPrm) (common.GetRes, error) {
if prm.BlobovniczaID == nil {
if prm.StorageID == nil {
// Nothing specified, try everything.
res, err := b.getBig(prm)
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
@ -22,7 +22,7 @@ func (b *BlobStor) Get(prm common.GetPrm) (common.GetRes, error) {
}
return b.getSmall(prm)
}
if *prm.BlobovniczaID == nil {
if len(prm.StorageID) == 0 {
return b.getBig(prm)
}
return b.getSmall(prm)

View file

@ -14,7 +14,7 @@ import (
// If the descriptor is present, only one sub-storage is tried,
// Otherwise, each sub-storage is tried in order.
func (b *BlobStor) GetRange(prm common.GetRangePrm) (common.GetRangeRes, error) {
if prm.BlobovniczaID == nil {
if prm.StorageID == nil {
// Nothing specified, try everything.
res, err := b.getRangeBig(prm)
if err == nil || !errors.As(err, new(apistatus.ObjectNotFound)) {
@ -22,7 +22,7 @@ func (b *BlobStor) GetRange(prm common.GetRangePrm) (common.GetRangeRes, error)
}
return b.getRangeSmall(prm)
}
if *prm.BlobovniczaID == nil {
if len(prm.StorageID) == 0 {
return b.getRangeBig(prm)
}
return b.getRangeSmall(prm)

View file

@ -15,7 +15,7 @@ type IterationElement struct {
addr oid.Address
blzID *blobovnicza.ID
descriptor []byte
}
// ObjectData returns the stored object in a binary representation.
@ -23,10 +23,9 @@ func (x IterationElement) ObjectData() []byte {
return x.data
}
// BlobovniczaID returns the identifier of Blobovnicza in which object is stored.
// Returns nil if the object isn't in Blobovnicza.
func (x IterationElement) BlobovniczaID() *blobovnicza.ID {
return x.blzID
// Descriptor returns the identifier of storage part where x is stored.
func (x IterationElement) Descriptor() []byte {
return x.descriptor
}
// Address returns the object address.
@ -89,7 +88,7 @@ func (b *BlobStor) Iterate(prm IteratePrm) (IterateRes, error) {
}
elem.addr = addr
elem.blzID = blobovnicza.NewIDFromBytes([]byte(p))
elem.descriptor = []byte(p)
return prm.handler(elem)
})
@ -103,7 +102,7 @@ func (b *BlobStor) Iterate(prm IteratePrm) (IterateRes, error) {
return IterateRes{}, fmt.Errorf("blobovniczas iterator failure: %w", err)
}
elem.blzID = nil
elem.descriptor = []byte{}
var fsPrm fstree.IterationPrm
fsPrm.WithIgnoreErrors(prm.ignoreErrors)
@ -136,11 +135,11 @@ func (b *BlobStor) Iterate(prm IteratePrm) (IterateRes, error) {
// IterateBinaryObjects is a helper function which iterates over BlobStor and passes binary objects to f.
// Errors related to object reading and unmarshaling are logged and skipped.
func IterateBinaryObjects(blz *BlobStor, f func(addr oid.Address, data []byte, blzID *blobovnicza.ID) error) error {
func IterateBinaryObjects(blz *BlobStor, f func(addr oid.Address, data []byte, descriptor []byte) error) error {
var prm IteratePrm
prm.SetIterationHandler(func(elem IterationElement) error {
return f(elem.Address(), elem.ObjectData(), elem.BlobovniczaID())
return f(elem.Address(), elem.ObjectData(), elem.Descriptor())
})
prm.IgnoreErrors()
prm.SetErrorHandler(func(addr oid.Address, err error) error {

View file

@ -5,7 +5,6 @@ import (
"os"
"testing"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobovnicza"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/common"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
@ -71,16 +70,16 @@ func TestIterateObjects(t *testing.T) {
require.NoError(t, err)
}
err := IterateBinaryObjects(blobStor, func(_ oid.Address, data []byte, blzID *blobovnicza.ID) error {
err := IterateBinaryObjects(blobStor, func(_ oid.Address, data []byte, descriptor []byte) error {
v, ok := mObjs[string(data)]
require.True(t, ok)
require.Equal(t, v.data, data)
if v.big {
require.Nil(t, blzID)
require.True(t, descriptor != nil && len(descriptor) == 0)
} else {
require.NotNil(t, blzID)
require.NotEmpty(t, descriptor)
}
delete(mObjs, string(data))