[#1318] metabase: Separate buckets with TS and GC marks

It allows storing information about object in both ways at the same time:
1. Metabase should know if an object is covered by a tombstone (that is
not expired yet);
2. It should be possible to physically delete objects covered by a
tombstone immediately (mark with GC) but keep tombstone knowledge.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-04-08 17:19:31 +03:00 committed by LeL
parent b74fb2b932
commit 8107c8d1a9
9 changed files with 163 additions and 84 deletions

View file

@ -1,7 +1,6 @@
package meta
import (
"bytes"
"errors"
"fmt"
@ -101,24 +100,37 @@ func (db *DB) exists(tx *bbolt.Tx, addr *addressSDK.Address) (exists bool, err e
}
// inGraveyard returns:
// * 0 if object is not in graveyard;
// * 1 if object is in graveyard with GC mark;
// * 2 if object is in graveyard with tombstone.
// * 0 if object is not marked for deletion;
// * 1 if object with GC mark;
// * 2 if object is covered with tombstone.
func inGraveyard(tx *bbolt.Tx, addr *addressSDK.Address) uint8 {
graveyard := tx.Bucket(graveyardBucketName)
if graveyard == nil {
// incorrect metabase state, does not make
// sense to check garbage bucket
return 0
}
val := graveyard.Get(addressKey(addr))
if val == nil {
garbageBCK := tx.Bucket(garbageBucketName)
if garbageBCK == nil {
// incorrect node state
return 0
}
val = garbageBCK.Get(addressKey(addr))
if val != nil {
// object has been marked with GC
return 1
}
// neither in the graveyard
// nor was marked with GC mark
return 0
}
if bytes.Equal(val, []byte(inhumeGCMarkValue)) {
return 1
}
// object in the graveyard
return 2
}