[#1176] metabase: Ignore locked objects in IterateExpired

Make `DB.IterateExpired` to not pass locked objects to the handler. The
method is used by GC, therefore it will not consider them as candidates
for deletion.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-02-15 21:22:06 +03:00 committed by LeL
parent 9508633a7e
commit dba3e58dc5
3 changed files with 31 additions and 1 deletions

View file

@ -38,7 +38,8 @@ type ExpiredObjectHandler func(*ExpiredObject) error
var ErrInterruptIterator = errors.New("iterator is interrupted")
// IterateExpired iterates over all objects in DB which are out of date
// relative to epoch.
// relative to epoch. Locked objects are not included (do not confuse
// with objects of type LOCK).
//
// If h returns ErrInterruptIterator, nil returns immediately.
// Returns other errors of h directly.
@ -83,6 +84,14 @@ func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler)
return fmt.Errorf("could not parse container ID of expired bucket: %w", err)
}
// Ignore locked objects.
//
// To slightly optimize performance we can check only REGULAR objects
// (only they can be locked), but it's more reliable.
if objectLocked(tx, *cnrID, *id) {
return nil
}
addr := addressSDK.NewAddress()
addr.SetContainerID(cnrID)
addr.SetObjectID(id)