[#11] Trim the old functionality

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-08-21 14:32:03 +03:00 committed by Alex Vanin
parent 783ec72d56
commit a87fdab324
235 changed files with 39 additions and 36211 deletions

0
pkg/core/object/.gitkeep Normal file
View file

View file

@ -1,94 +0,0 @@
package object
// ExtendedHeaderType represents the enumeration
// of extended header types of the NeoFS object.
type ExtendedHeaderType uint32
// ExtendedHeader represents the extended
// header of NeoFS object.
type ExtendedHeader struct {
typ ExtendedHeaderType
val interface{}
}
// Type returns the extended header type.
func (h ExtendedHeader) Type() ExtendedHeaderType {
return h.typ
}
// SetType sets the extended header type.
func (h *ExtendedHeader) SetType(v ExtendedHeaderType) {
h.typ = v
}
// Value returns the extended header value.
//
// In the case of a reference type, the value is
// returned by reference, so value mutations affect
// header state. Therefore, callers must first copy
// the value before changing manipulations.
func (h ExtendedHeader) Value() interface{} {
return h.val
}
// SetValue sets the extended header value.
//
// Caller must take into account that each type of
// header usually has a limited set of expected
// value types.
//
// In the case of a reference type, the value is set
// by reference, so source value mutations affect
// header state. Therefore, callers must first copy
// the source value before changing manipulations.
func (h *ExtendedHeader) SetValue(v interface{}) {
h.val = v
}
// TypeFromUint32 converts builtin
// uint32 value to Epoch.
//
// Try to avoid direct cast for
// better portability.
func TypeFromUint32(v uint32) ExtendedHeaderType {
return ExtendedHeaderType(v)
}
// TypeToUint32 converts Epoch value
// to builtin uint32.
//
// Try to avoid direct cast for
// better portability.
func TypeToUint32(v ExtendedHeaderType) uint32 {
return uint32(v)
}
// TypesEQ reports whether t1 and t2 are the same ExtendedHeaderType.
//
// Function defines the relation of equality
// between two ExtendedHeaderType. Try to avoid comparison through
// "==" operator for better portability.
func TypesEQ(t1, t2 ExtendedHeaderType) bool {
return TypeToUint32(t1) == TypeToUint32(t2)
}
// TypesLT reports whether t1 ExtendedHeaderType
// is less than t2.
//
// Function defines the "less than" relation
// between two ExtendedHeaderType. Try to avoid
// comparison through "<" operator for better portability.
func TypesLT(t1, t2 ExtendedHeaderType) bool {
return TypeToUint32(t1) < TypeToUint32(t2)
}
// TypesGT reports whether t1 ExtendedHeaderType
// is greater than t2.
//
// Function defines the "greater than" relation
// between two ExtendedHeaderType. Try to avoid
// comparison through ">" operator for better portability.
func TypesGT(t1, t2 ExtendedHeaderType) bool {
return TypeToUint32(t1) > TypeToUint32(t2)
}

View file

@ -1,25 +0,0 @@
package object
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestExtendedHeader_Type(t *testing.T) {
h := new(ExtendedHeader)
ht := TypeFromUint32(3)
h.SetType(ht)
require.True(t, TypesEQ(ht, h.Type()))
}
func TestExtendedHeader_Value(t *testing.T) {
h := new(ExtendedHeader)
val := 100
h.SetValue(val)
require.Equal(t, val, h.Value())
}

View file

@ -1,73 +0,0 @@
package object
import (
"errors"
)
// Header represents NeoFS object header.
type Header struct {
// SystemHeader is an obligatory part of any object header.
// It is used to set the identity and basic parameters of
// the object.
//
// Header must inherit all the methods of SystemHeader,
// so the SystemHeader is embedded in Header.
SystemHeader
extendedHeaders []ExtendedHeader // extended headers
}
// ErrNilHeader is returned by functions that expect
// a non-nil Header pointer, but received nil.
var ErrNilHeader = errors.New("object header is nil")
// ExtendedHeaders returns the extended headers of header.
//
// Changing the result is unsafe and affects the header.
// In order to prevent state mutations, use CopyExtendedHeaders.
func (h *Header) ExtendedHeaders() []ExtendedHeader {
return h.extendedHeaders
}
// CopyExtendedHeaders returns the copy of extended headers.
//
// Changing the result is safe and does not affect the header.
//
// Returns nil if header is nil.
func CopyExtendedHeaders(h *Header) []ExtendedHeader {
if h == nil {
return nil
}
res := make([]ExtendedHeader, len(h.extendedHeaders))
copy(res, h.extendedHeaders)
return res
}
// SetExtendedHeaders sets the extended headers of the header.
//
// Subsequent changing the source slice is unsafe and affects
// the header. In order to prevent state mutations, use
// SetExtendedHeadersCopy.
func (h *Header) SetExtendedHeaders(v []ExtendedHeader) {
h.extendedHeaders = v
}
// SetExtendedHeadersCopy copies extended headers and sets the copy
// as the object extended headers.
//
// Subsequent changing the source slice is safe and does not affect
// the header.
//
// SetExtendedHeadersCopy does nothing if Header is nil.
func SetExtendedHeadersCopy(h *Header, hs []ExtendedHeader) {
if h == nil {
return
}
h.extendedHeaders = make([]ExtendedHeader, len(hs))
copy(h.extendedHeaders, hs)
}

View file

@ -1,98 +0,0 @@
package object
import (
"testing"
"github.com/stretchr/testify/require"
)
func testHeaders(num uint32) []ExtendedHeader {
res := make([]ExtendedHeader, num)
for i := uint32(0); i < num; i++ {
res[i].SetType(TypeFromUint32(i))
res[i].SetValue(i)
}
return res
}
func TestObject_ExtendedHeaders(t *testing.T) {
h := new(Header)
hs := testHeaders(2)
h.SetExtendedHeaders(hs)
require.Equal(t, hs, h.ExtendedHeaders())
}
func TestCopyExtendedHeaders(t *testing.T) {
require.Nil(t, CopyExtendedHeaders(nil))
h := new(Header)
// set initial headers
initHs := testHeaders(2)
h.SetExtendedHeaders(initHs)
// get extended headers copy
hsCopy := CopyExtendedHeaders(h)
// change the copy
hsCopy[0] = hsCopy[1]
// check that extended headers have not changed
require.Equal(t, initHs, h.ExtendedHeaders())
}
func TestSetExtendedHeadersCopy(t *testing.T) {
require.NotPanics(t, func() {
SetExtendedHeadersCopy(nil, nil)
})
h := new(Header)
// create source headers
srcHs := testHeaders(2)
// copy and set headers
SetExtendedHeadersCopy(h, srcHs)
// get extended headers
objHs := h.ExtendedHeaders()
// change the source headers
srcHs[0] = srcHs[1]
// check that headeres have not changed
require.Equal(t, objHs, h.ExtendedHeaders())
}
func TestHeaderRelations(t *testing.T) {
items := []struct {
relFn func(ExtendedHeaderType, ExtendedHeaderType) bool
base, ok, fail uint32
}{
{relFn: TypesEQ, base: 1, ok: 1, fail: 2},
{relFn: TypesLT, base: 1, ok: 2, fail: 0},
{relFn: TypesGT, base: 1, ok: 0, fail: 2},
}
for _, item := range items {
require.True(t,
item.relFn(
TypeFromUint32(item.base),
TypeFromUint32(item.ok),
),
)
require.False(t,
item.relFn(
TypeFromUint32(item.base),
TypeFromUint32(item.fail),
),
)
}
}

View file

@ -1,63 +0,0 @@
package headers
import (
"github.com/nspcc-dev/neofs-node/pkg/core/object"
)
// Header represents object extended header.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/object.ExtendedHeader.
type Header = object.ExtendedHeader
// Type represents extended header type.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/object.ExtendedHeaderType.
type Type = object.ExtendedHeaderType
const (
// this is the only place where this cast is appropriate,
// use object.TypeFromUint32 instead.
lowerUndefined = Type(iota) // lower unsupported Type value
// TypeLink is the type of object reference header.
TypeLink
// TypeUser is the of user key-value string header.
TypeUser
// TypeTransform is the type of transformation mark header.
TypeTransform
// TypeTombstone is the type of tombstone mark header.
TypeTombstone
// TypeSessionToken is the type of session token header.
TypeSessionToken
// TypeHomomorphicHash is the type of homomorphic hash header.
TypeHomomorphicHash
// TypePayloadChecksum is the type of payload checksum header.
TypePayloadChecksum
// TypeIntegrity is the type of integrity header.
TypeIntegrity
// TypeStorageGroup is the type of storage group header.
TypeStorageGroup
// TypePublicKey is the type of public key header.
TypePublicKey
upperUndefined // upper unsupported Type value
)
// SupportedType returns true if Type is
// the known type of extended header. Each
// supported type has named constant.
func SupportedType(t Type) bool {
return object.TypesGT(t, lowerUndefined) &&
object.TypesLT(t, upperUndefined)
}

View file

@ -1,34 +0,0 @@
package headers
import (
"testing"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/stretchr/testify/require"
)
func TestSupportedType(t *testing.T) {
for _, typ := range []Type{
TypeLink,
TypeUser,
TypeTransform,
TypeTombstone,
TypeSessionToken,
TypeHomomorphicHash,
TypePayloadChecksum,
TypeIntegrity,
TypeStorageGroup,
TypePublicKey,
} {
require.True(t, SupportedType(typ))
}
for _, typ := range []Type{
lowerUndefined,
upperUndefined,
object.TypeFromUint32(object.TypeToUint32(lowerUndefined) - 1),
object.TypeFromUint32(object.TypeToUint32(upperUndefined) + 1),
} {
require.False(t, SupportedType(typ))
}
}

View file

@ -1,45 +0,0 @@
package headers
// UserHeader is a value of object extended header
// that carries user string key-value pairs.
//
// All user headers must be type of TypeUser.
// All user header must have UserHeader pointer value.
type UserHeader struct {
key, val string
}
// NewUserHeader creates, initialized and returns
// the user extended header.
func NewUserHeader(key, val string) *Header {
res := new(Header)
res.SetType(TypeUser)
res.SetValue(&UserHeader{
key: key,
val: val,
})
return res
}
// Key returns the user header key.
func (u UserHeader) Key() string {
return u.key
}
// SetKey sets the user header key.
func (u *UserHeader) SetKey(key string) {
u.key = key
}
// Value returns the user header value.
func (u UserHeader) Value() string {
return u.val
}
// SetValue sets the user header value.
func (u *UserHeader) SetValue(val string) {
u.val = val
}

View file

@ -1,45 +0,0 @@
package headers
import (
"testing"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/stretchr/testify/require"
)
func TestUserHeader_Key(t *testing.T) {
h := new(UserHeader)
key := "random key"
h.SetKey(key)
require.Equal(t, key, h.Key())
}
func TestUserHeader_Value(t *testing.T) {
h := new(UserHeader)
val := "random value"
h.SetValue(val)
require.Equal(t, val, h.Value())
}
func TestNewUserHeader(t *testing.T) {
key := "user key"
val := "user val"
h := NewUserHeader(key, val)
require.True(t,
object.TypesEQ(
TypeUser,
h.Type(),
),
)
uh := h.Value().(*UserHeader)
require.Equal(t, key, uh.Key())
require.Equal(t, val, uh.Value())
}

View file

@ -1,61 +0,0 @@
package object
import (
"github.com/nspcc-dev/neofs-api-go/refs"
)
// ID represents the object identifier.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-api-go/refs.ObjectID.
// FIXME: object ID should be defined in core package.
type ID = refs.ObjectID
// Address represents NeoFS Object address.
// Acts as a reference to the object.
type Address struct {
cid CID
id ID
}
// CID return the identifier of the container
// that the object belongs to.
func (a Address) CID() CID {
return a.cid
}
// SetCID sets the identifier of the container
// that the object belongs to.
func (a *Address) SetCID(v CID) {
a.cid = v
}
// ID returns the unique identifier of the
// object in container.
func (a Address) ID() ID {
return a.id
}
// SetID sets the unique identifier of the
// object in container.
func (a *Address) SetID(v ID) {
a.id = v
}
// AddressFromObject returns an address based
// on the object's header.
//
// Returns nil on nil object.
func AddressFromObject(o *Object) *Address {
if o == nil {
return nil
}
a := new(Address)
a.SetCID(o.CID())
a.SetID(o.ID())
return a
}

View file

@ -1,42 +0,0 @@
package object
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestAddress_CID(t *testing.T) {
a := new(Address)
cid := CID{1, 2, 3}
a.SetCID(cid)
require.Equal(t, cid, a.CID())
}
func TestAddress_ID(t *testing.T) {
a := new(Address)
id := ID{1, 2, 3}
a.SetID(id)
require.Equal(t, id, a.ID())
}
func TestAddressFromObject(t *testing.T) {
require.Nil(t, AddressFromObject(nil))
o := new(Object)
cid := CID{4, 5, 6}
o.SetCID(cid)
id := ID{1, 2, 3}
o.SetID(id)
a := AddressFromObject(o)
require.Equal(t, cid, a.CID())
require.Equal(t, id, a.ID())
}

View file

@ -1,76 +0,0 @@
package object
import (
"errors"
)
// Object represents NeoFS Object.
type Object struct {
// Header is an obligatory part of any object.
// It is used to carry any additional information
// besides payload.
//
// Object must inherit all the methods of Header,
// so the Header is embedded in Object.
Header
payload []byte // payload bytes
}
// ErrNilObject is returned by functions that expect
// a non-nil Object pointer, but received nil.
var ErrNilObject = errors.New("object is nil")
// Payload returns payload bytes of the object.
//
// Changing the result is unsafe and affects
// the object. In order to prevent state
// mutations, use CopyPayload.
func (o *Object) Payload() []byte {
return o.payload
}
// CopyPayload returns the copy of
// object payload.
//
// Changing the result is safe and
// does not affect the object.
//
// CopyPayload returns nil if object is nil.
func CopyPayload(o *Object) []byte {
if o == nil {
return nil
}
res := make([]byte, len(o.payload))
copy(res, o.payload)
return res
}
// SetPayload sets objecyt payload bytes.
//
// Subsequent changing the source slice
// is unsafe and affects the object.
// In order to prevent state mutations,
// use SetPayloadCopy.
func (o *Object) SetPayload(v []byte) {
o.payload = v
}
// SetPayloadCopy copies slice bytes and sets
// the copy as object payload.
//
// Subsequent changing the source slice
// is safe and does not affect the object.
//
// SetPayloadCopy does nothing if object is nil.
func SetPayloadCopy(o *Object, payload []byte) {
if o == nil {
return
}
o.payload = make([]byte, len(payload))
copy(o.payload, payload)
}

View file

@ -1,58 +0,0 @@
package object
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestObject_Payload(t *testing.T) {
o := new(Object)
payload := []byte{1, 2, 3}
o.SetPayload(payload)
require.Equal(t, payload, o.Payload())
}
func TestCopyPayload(t *testing.T) {
require.Nil(t, CopyPayload(nil))
o := new(Object)
// set initial node key
initPayload := []byte{1, 2, 3}
o.SetPayload(initPayload)
// get payload copy
pCopy := CopyPayload(o)
// change the copy
pCopy[0]++
// check that payload has not changed
require.Equal(t, initPayload, o.Payload())
}
func TestSetPayloadCopy(t *testing.T) {
require.NotPanics(t, func() {
SetExtendedHeadersCopy(nil, nil)
})
o := new(Object)
// create source payload
srcPayload := []byte{1, 2, 3}
// copy and set payload
SetPayloadCopy(o, srcPayload)
// get payload
objPayload := o.Payload()
// change the source payload
srcPayload[0]++
// check that payload has not changed
require.Equal(t, objPayload, o.Payload())
}

View file

@ -1,61 +0,0 @@
package storage
import (
"errors"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
)
// Object represents the NeoFS Object.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/object.Object.
type Object = object.Object
// Address represents the address of
// NeoFS Object.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/object.Address.
type Address = object.Address
// Storage is an interface that wraps
// basic object storage methods.
type Storage interface {
// Put saves pointed object to the underlying storage.
// It returns object address for reference and any error
// encountered that caused the saving to interrupt.
//
// Put must return object.ErrNilObject on nil-pointer.
//
// Implementations must not modify the object through the pointer (even temporarily).
// Implementations must not retain the object pointer.
//
// Object rewriting behavior is dictated by implementation.
Put(*Object) (*Address, error)
// Get reads the object from the storage by address.
// It returns the pointer to requested object and any error encountered.
//
// Get must return exactly one non-nil value.
// Get must return ErrNotFound if the object is not in storage.
//
// Implementations must not retain the object pointer and modify
// the object through it.
Get(Address) (*Object, error)
// Delete removes the object from the storage.
// It returns any error encountered that caused the deletion to interrupt.
//
// Delete must return nil if object was successfully deleted.
//
// Behavior when deleting a nonexistent object is dictated by implementation.
Delete(Address) error
}
// ErrNotFound is the error returned when object was not found in storage.
var ErrNotFound = errors.New("object not found")
// ErrNilStorage is the error returned by functions that
// expect a non-nil object storage implementation, but received nil.
var ErrNilStorage = errors.New("object storage is nil")

View file

@ -1,88 +0,0 @@
package test
import (
"sync"
"testing"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object/storage"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
)
type testStorage struct {
*sync.RWMutex
items map[storage.Address]*storage.Object
}
func (s *testStorage) Put(o *storage.Object) (*storage.Address, error) {
if o == nil {
return nil, object.ErrNilObject
}
a := object.AddressFromObject(o)
s.Lock()
s.items[*a] = o
s.Unlock()
return a, nil
}
func (s *testStorage) Get(a storage.Address) (*storage.Object, error) {
s.RLock()
o, ok := s.items[a]
s.RUnlock()
if !ok {
return nil, storage.ErrNotFound
}
return o, nil
}
func (s *testStorage) Delete(a storage.Address) error {
s.Lock()
delete(s.items, a)
s.Unlock()
return nil
}
// New creates new container storage
// that stores containers in go-builtin map.
func New() storage.Storage {
return &testStorage{
RWMutex: new(sync.RWMutex),
items: make(map[storage.Address]*storage.Object),
}
}
// Storage conducts testing of object
// storage for interface specification.
//
// Storage must be empty.
func Storage(t *testing.T, s storage.Storage) {
_, err := s.Put(nil)
require.True(t, errors.Is(err, object.ErrNilObject))
a := new(object.Address)
_, err = s.Get(*a)
require.True(t, errors.Is(err, storage.ErrNotFound))
o := new(object.Object)
o.SetID(object.ID{1, 2, 3})
a, err = s.Put(o)
require.NoError(t, err)
o2, err := s.Get(*a)
require.NoError(t, err)
require.Equal(t, o, o2)
require.NoError(t, s.Delete(*a))
_, err = s.Get(*a)
require.True(t, errors.Is(err, storage.ErrNotFound))
}

View file

@ -1,11 +0,0 @@
package test
import (
"testing"
)
func TestNewStorage(t *testing.T) {
s := New()
Storage(t, s)
}

View file

@ -1,107 +0,0 @@
package object
import (
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap/epoch"
)
// CID represents the container identifier.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/container.ID.
type CID = container.ID
// OwnerID represents the container
// owner identifier.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/container.OwnerID.
type OwnerID = container.OwnerID
// Epoch represents the NeoFS epoch number.
//
// It is a type alias of
// github.com/nspcc-dev/neofs-node/pkg/core/netmap/epoch.Epoch.
type Epoch = epoch.Epoch
// SystemHeader represents the
// system header of NeoFS Object.
type SystemHeader struct {
version uint64 // object version
payloadLen uint64 // length of the payload bytes
id ID // object ID
cid CID // container ID
ownerID OwnerID // object owner ID
creatEpoch Epoch // creation epoch number
}
// Version returns the object version number.
func (s *SystemHeader) Version() uint64 {
return s.version
}
// SetVersion sets the object version number.
func (s *SystemHeader) SetVersion(v uint64) {
s.version = v
}
// PayloadLength returns the length of the
// object payload bytes.
func (s *SystemHeader) PayloadLength() uint64 {
return s.payloadLen
}
// SetPayloadLength sets the length of the object
// payload bytes.
func (s *SystemHeader) SetPayloadLength(v uint64) {
s.payloadLen = v
}
// ID returns the object identifier.
func (s *SystemHeader) ID() ID {
return s.id
}
// SetID sets the object identifier.
func (s *SystemHeader) SetID(v ID) {
s.id = v
}
// CID returns the container identifier
// to which the object belongs.
func (s *SystemHeader) CID() CID {
return s.cid
}
// SetCID sets the container identifier
// to which the object belongs.
func (s *SystemHeader) SetCID(v CID) {
s.cid = v
}
// OwnerID returns the object owner identifier.
func (s *SystemHeader) OwnerID() OwnerID {
return s.ownerID
}
// SetOwnerID sets the object owner identifier.
func (s *SystemHeader) SetOwnerID(v OwnerID) {
s.ownerID = v
}
// CreationEpoch returns the epoch number
// in which the object was created.
func (s *SystemHeader) CreationEpoch() Epoch {
return s.creatEpoch
}
// SetCreationEpoch sets the epoch number
// in which the object was created.
func (s *SystemHeader) SetCreationEpoch(v Epoch) {
s.creatEpoch = v
}

View file

@ -1,62 +0,0 @@
package object
import (
"testing"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap/epoch"
"github.com/stretchr/testify/require"
)
func TestSystemHeader_Version(t *testing.T) {
h := new(SystemHeader)
v := uint64(7)
h.SetVersion(v)
require.Equal(t, v, h.Version())
}
func TestSystemHeader_PayloadLength(t *testing.T) {
h := new(SystemHeader)
ln := uint64(3)
h.SetPayloadLength(ln)
require.Equal(t, ln, h.PayloadLength())
}
func TestSystemHeader_ID(t *testing.T) {
h := new(SystemHeader)
id := ID{1, 2, 3}
h.SetID(id)
require.Equal(t, id, h.ID())
}
func TestSystemHeader_CID(t *testing.T) {
h := new(SystemHeader)
cid := CID{1, 2, 3}
h.SetCID(cid)
require.Equal(t, cid, h.CID())
}
func TestSystemHeader_OwnerID(t *testing.T) {
h := new(SystemHeader)
ownerID := OwnerID{1, 2, 3}
h.SetOwnerID(ownerID)
require.Equal(t, ownerID, h.OwnerID())
}
func TestSystemHeader_CreationEpoch(t *testing.T) {
h := new(SystemHeader)
ep := epoch.FromUint64(1)
h.SetCreationEpoch(ep)
require.True(t, epoch.EQ(ep, h.CreationEpoch()))
}