[#1502] meta: Add IsLocked method

It gets an object and returns its locking status.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2022-11-12 14:46:44 +03:00 committed by fyrchik
parent 7ef0303e13
commit 9a039ba582
2 changed files with 76 additions and 0 deletions

View file

@ -175,3 +175,35 @@ func freePotentialLocks(tx *bbolt.Tx, idCnr cid.ID, locker oid.ID) error {
return 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) {
return res, db.boltDB.View(func(tx *bbolt.Tx) error {
res.locked = objectLocked(tx, prm.addr.Container(), prm.addr.Object())
return nil
})
}

View file

@ -169,6 +169,50 @@ func TestDB_Lock(t *testing.T) {
})
}
func TestDB_IsLocked(t *testing.T) {
db := newDB(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)
require.NoError(t, err)
require.True(t, res.Locked())
}
// some rand obj
prm.SetAddress(oidtest.Address())
res, err := db.IsLocked(prm)
require.NoError(t, err)
require.False(t, res.Locked())
// existing but not locked obj
obj := objecttest.Object()
var putPrm meta.PutPrm
putPrm.SetObject(obj)
_, err = db.Put(putPrm)
require.NoError(t, err)
prm.SetAddress(objectcore.AddressOf(obj))
res, err = db.IsLocked(prm)
require.NoError(t, err)
require.False(t, res.Locked())
}
// putAndLockObj puts object, returns it and its locker.
func putAndLockObj(t *testing.T, db *meta.DB, numOfLockedObjs int) ([]*object.Object, *object.Object) {
cnr := cidtest.ID()