forked from TrueCloudLab/frostfs-node
[#229] blobovnicza: Store objects in a binary format
In previous implementation Blobovnicza's stored objects in protocol format which did not allow working with externally compressed objects. To achieve this goal, operations Get and Put no longer work with the structure of the object, but only with abstract binary data. Operation GetRange has become incorrect in its original purpose to receive the payload range. In this regard, BlobStor receives the payload range of the object through Get operation. In the future either Blobovnicza will learn to compress objects by itself, or the GetRange operation will be eliminated. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
3d77fdb347
commit
eaae5a5dd7
6 changed files with 73 additions and 58 deletions
|
@ -55,12 +55,15 @@ func testObject(sz uint64) *object.Object {
|
|||
}
|
||||
|
||||
func testPutGet(t *testing.T, blz *Blobovnicza, sz uint64, expPut, expGet error) *objectSDK.Address {
|
||||
// create new object
|
||||
obj := testObject(sz)
|
||||
// create binary object
|
||||
data := make([]byte, sz)
|
||||
|
||||
addr := testAddress()
|
||||
|
||||
// try to save object in Blobovnicza
|
||||
pPut := new(PutPrm)
|
||||
pPut.SetObject(obj)
|
||||
pPut.SetAddress(addr)
|
||||
pPut.SetMarshaledObject(data)
|
||||
_, err := blz.Put(pPut)
|
||||
require.True(t, errors.Is(err, expPut))
|
||||
|
||||
|
@ -68,12 +71,12 @@ func testPutGet(t *testing.T, blz *Blobovnicza, sz uint64, expPut, expGet error)
|
|||
return nil
|
||||
}
|
||||
|
||||
testGet(t, blz, obj.Address(), obj, expGet)
|
||||
testGet(t, blz, addr, data, expGet)
|
||||
|
||||
return obj.Address()
|
||||
return addr
|
||||
}
|
||||
|
||||
func testGet(t *testing.T, blz *Blobovnicza, addr *objectSDK.Address, expObj *object.Object, expErr error) {
|
||||
func testGet(t *testing.T, blz *Blobovnicza, addr *objectSDK.Address, expObj []byte, expErr error) {
|
||||
pGet := new(GetPrm)
|
||||
pGet.SetAddress(addr)
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package blobovnicza
|
|||
import (
|
||||
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||
"github.com/pkg/errors"
|
||||
"go.etcd.io/bbolt"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -15,7 +14,7 @@ type GetPrm struct {
|
|||
|
||||
// GetRes groups resulting values of Get operation.
|
||||
type GetRes struct {
|
||||
obj *object.Object
|
||||
obj []byte
|
||||
}
|
||||
|
||||
// SetAddress sets address of the requested object.
|
||||
|
@ -23,8 +22,8 @@ func (p *GetPrm) SetAddress(addr *objectSDK.Address) {
|
|||
p.addr = addr
|
||||
}
|
||||
|
||||
// Object returns the requested object.
|
||||
func (p *GetRes) Object() *object.Object {
|
||||
// Object returns binary representation of the requested object.
|
||||
func (p *GetRes) Object() []byte {
|
||||
return p.obj
|
||||
}
|
||||
|
||||
|
@ -64,15 +63,7 @@ func (b *Blobovnicza) Get(prm *GetPrm) (*GetRes, error) {
|
|||
return nil, object.ErrNotFound
|
||||
}
|
||||
|
||||
// TODO: add decompression step
|
||||
|
||||
// unmarshal the object
|
||||
obj := object.New()
|
||||
if err := obj.Unmarshal(data); err != nil {
|
||||
return nil, errors.Wrap(err, "could not unmarshal the object")
|
||||
}
|
||||
|
||||
return &GetRes{
|
||||
obj: obj,
|
||||
obj: data,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -49,9 +49,14 @@ func (b *Blobovnicza) GetRange(prm *GetRangePrm) (*GetRangeRes, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// FIXME: code below is incorrect because Get returns raw object data
|
||||
// so we should unmarshal payload from it before. If blobovnicza
|
||||
// stores objects in non-protocol format (e.g. compressed)
|
||||
// then it should not provide GetRange method.
|
||||
|
||||
from := prm.rng.GetOffset()
|
||||
to := from + prm.rng.GetLength()
|
||||
payload := res.obj.Payload()
|
||||
payload := res.obj
|
||||
|
||||
if from > to {
|
||||
return nil, errors.Errorf("invalid range [%d:%d]", from, to)
|
||||
|
|
|
@ -2,7 +2,6 @@ package blobovnicza
|
|||
|
||||
import (
|
||||
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||
"github.com/pkg/errors"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -11,8 +10,6 @@ import (
|
|||
type PutPrm struct {
|
||||
addr *objectSDK.Address
|
||||
|
||||
obj *object.Object
|
||||
|
||||
objData []byte
|
||||
}
|
||||
|
||||
|
@ -31,11 +28,6 @@ func (p *PutPrm) SetAddress(addr *objectSDK.Address) {
|
|||
p.addr = addr
|
||||
}
|
||||
|
||||
// SetObject sets the object.
|
||||
func (p *PutPrm) SetObject(obj *object.Object) {
|
||||
p.obj = obj
|
||||
}
|
||||
|
||||
// SetMarshaledObject sets binary representation of the object.
|
||||
func (p *PutPrm) SetMarshaledObject(data []byte) {
|
||||
p.objData = data
|
||||
|
@ -56,9 +48,7 @@ func (p *PutPrm) SetMarshaledObject(data []byte) {
|
|||
func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
||||
addr := prm.addr
|
||||
if addr == nil {
|
||||
if addr = prm.obj.Address(); addr == nil {
|
||||
return nil, errNilAddress
|
||||
}
|
||||
return nil, errNilAddress
|
||||
}
|
||||
|
||||
err := b.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
|
@ -66,19 +56,8 @@ func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
|||
return ErrFull
|
||||
}
|
||||
|
||||
// marshal the object
|
||||
data := prm.objData
|
||||
if data == nil {
|
||||
var err error
|
||||
|
||||
if data, err = prm.obj.Marshal(); err != nil {
|
||||
return errors.Wrapf(err, "(%T) could not marshal the object", b)
|
||||
}
|
||||
}
|
||||
// TODO: add compression step
|
||||
|
||||
// calculate size
|
||||
sz := uint64(len(data))
|
||||
sz := uint64(len(prm.objData))
|
||||
|
||||
// get bucket for size
|
||||
buck := tx.Bucket(bucketForSize(sz))
|
||||
|
@ -90,7 +69,7 @@ func (b *Blobovnicza) Put(prm *PutPrm) (*PutRes, error) {
|
|||
}
|
||||
|
||||
// save the object in bucket
|
||||
if err := buck.Put(addressKey(addr), data); err != nil {
|
||||
if err := buck.Put(addressKey(addr), prm.objData); err != nil {
|
||||
return errors.Wrapf(err, "(%T) could not save object in bucket", b)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue