forked from TrueCloudLab/frostfs-node
[#1147] node: Implement Lock\Delete
requests for EC object
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
parent
88b8ddd902
commit
6130650bb6
20 changed files with 371 additions and 66 deletions
|
@ -20,12 +20,14 @@ import (
|
|||
|
||||
// ExistsPrm groups the parameters of Exists operation.
|
||||
type ExistsPrm struct {
|
||||
addr oid.Address
|
||||
addr oid.Address
|
||||
paddr oid.Address
|
||||
}
|
||||
|
||||
// ExistsRes groups the resulting values of Exists operation.
|
||||
type ExistsRes struct {
|
||||
exists bool
|
||||
locked bool
|
||||
}
|
||||
|
||||
var ErrLackSplitInfo = logicerr.New("no split info on parent object")
|
||||
|
@ -35,11 +37,21 @@ func (p *ExistsPrm) SetAddress(addr oid.Address) {
|
|||
p.addr = addr
|
||||
}
|
||||
|
||||
// SetParent is an Exists option to set objects parent.
|
||||
func (p *ExistsPrm) SetParent(addr oid.Address) {
|
||||
p.paddr = addr
|
||||
}
|
||||
|
||||
// Exists returns the fact that the object is in the metabase.
|
||||
func (p ExistsRes) Exists() bool {
|
||||
return p.exists
|
||||
}
|
||||
|
||||
// Locked returns the fact that the object is locked.
|
||||
func (p ExistsRes) Locked() bool {
|
||||
return p.locked
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
|
@ -70,7 +82,7 @@ func (db *DB) Exists(ctx context.Context, prm ExistsPrm) (res ExistsRes, err err
|
|||
currEpoch := db.epochState.CurrentEpoch()
|
||||
|
||||
err = db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
res.exists, err = db.exists(tx, prm.addr, currEpoch)
|
||||
res.exists, res.locked, err = db.exists(tx, prm.addr, prm.paddr, currEpoch)
|
||||
|
||||
return err
|
||||
})
|
||||
|
@ -78,15 +90,19 @@ func (db *DB) Exists(ctx context.Context, prm ExistsPrm) (res ExistsRes, err err
|
|||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists bool, err error) {
|
||||
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, parent oid.Address, currEpoch uint64) (bool, bool, error) {
|
||||
var locked bool
|
||||
if !parent.Equals(oid.Address{}) {
|
||||
locked = objectLocked(tx, parent.Container(), parent.Object())
|
||||
}
|
||||
// check graveyard and object expiration first
|
||||
switch objectStatus(tx, addr, currEpoch) {
|
||||
case 1:
|
||||
return false, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||
return false, locked, logicerr.Wrap(new(apistatus.ObjectNotFound))
|
||||
case 2:
|
||||
return false, logicerr.Wrap(new(apistatus.ObjectAlreadyRemoved))
|
||||
return false, locked, logicerr.Wrap(new(apistatus.ObjectAlreadyRemoved))
|
||||
case 3:
|
||||
return false, ErrObjectIsExpired
|
||||
return false, locked, ErrObjectIsExpired
|
||||
}
|
||||
|
||||
objKey := objectKey(addr.Object(), make([]byte, objectKeySize))
|
||||
|
@ -96,25 +112,25 @@ func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists b
|
|||
|
||||
// if graveyard is empty, then check if object exists in primary bucket
|
||||
if inBucket(tx, primaryBucketName(cnr, key), objKey) {
|
||||
return true, nil
|
||||
return true, locked, nil
|
||||
}
|
||||
|
||||
// if primary bucket is empty, then check if object exists in parent bucket
|
||||
if inBucket(tx, parentBucketName(cnr, key), objKey) {
|
||||
splitInfo, err := getSplitInfo(tx, cnr, objKey)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, locked, err
|
||||
}
|
||||
|
||||
return false, logicerr.Wrap(objectSDK.NewSplitInfoError(splitInfo))
|
||||
return false, locked, logicerr.Wrap(objectSDK.NewSplitInfoError(splitInfo))
|
||||
}
|
||||
// if parent bucket is empty, then check if object exists in ec bucket
|
||||
if data := getFromBucket(tx, ecInfoBucketName(cnr, key), objKey); len(data) != 0 {
|
||||
return false, getECInfoError(tx, cnr, data)
|
||||
return false, locked, getECInfoError(tx, cnr, data)
|
||||
}
|
||||
|
||||
// if parent bucket is empty, then check if object exists in typed buckets
|
||||
return firstIrregularObjectType(tx, cnr, objKey) != objectSDK.TypeRegular, nil
|
||||
return firstIrregularObjectType(tx, cnr, objKey) != objectSDK.TypeRegular, locked, nil
|
||||
}
|
||||
|
||||
// objectStatus returns:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue