[#199] Add CleanUp method to remove empty buckets from metabase
Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
7fb87aac85
commit
74d44beb99
1 changed files with 85 additions and 0 deletions
85
pkg/local_object_storage/metabase/v2/cleanup.go
Normal file
85
pkg/local_object_storage/metabase/v2/cleanup.go
Normal file
|
@ -0,0 +1,85 @@
|
|||
package meta
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
func (db *DB) CleanUp() error {
|
||||
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
return tx.ForEach(func(name []byte, b *bbolt.Bucket) error {
|
||||
switch {
|
||||
case isFKBTBucket(name):
|
||||
cleanUpFKBT(tx, name, b)
|
||||
case isListBucket(name):
|
||||
cleanUpListBucket(tx, name, b)
|
||||
default:
|
||||
cleanUpUniqueBucket(tx, name, b)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func isFKBTBucket(name []byte) bool {
|
||||
bucketName := string(name)
|
||||
|
||||
switch {
|
||||
case
|
||||
strings.Contains(bucketName, userAttributePostfix),
|
||||
strings.Contains(bucketName, ownerPostfix):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isListBucket(name []byte) bool {
|
||||
bucketName := string(name)
|
||||
|
||||
switch {
|
||||
case
|
||||
strings.Contains(bucketName, payloadHashPostfix),
|
||||
strings.Contains(bucketName, parentPostfix):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func cleanUpUniqueBucket(tx *bbolt.Tx, name []byte, b *bbolt.Bucket) {
|
||||
if b.Stats().KeyN == 0 {
|
||||
_ = tx.DeleteBucket(name) // ignore error, best effort there
|
||||
}
|
||||
}
|
||||
|
||||
func cleanUpFKBT(tx *bbolt.Tx, name []byte, b *bbolt.Bucket) {
|
||||
removedBuckets := 0
|
||||
remainingBuckets := b.Stats().BucketN - 1
|
||||
|
||||
_ = b.ForEach(func(k, _ []byte) error {
|
||||
fkbtRoot := b.Bucket(k)
|
||||
if fkbtRoot == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if fkbtRoot.Stats().KeyN == 0 {
|
||||
err := b.DeleteBucket(k)
|
||||
if err == nil {
|
||||
removedBuckets++
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if remainingBuckets == removedBuckets {
|
||||
_ = tx.DeleteBucket(name) // ignore error, best effort there
|
||||
}
|
||||
}
|
||||
|
||||
func cleanUpListBucket(tx *bbolt.Tx, name []byte, b *bbolt.Bucket) {
|
||||
cleanUpUniqueBucket(tx, name, b)
|
||||
}
|
Loading…
Reference in a new issue