Dmitrii Stepanov
7eb46404a1
All checks were successful
Vulncheck / Vulncheck (pull_request) Successful in 2m27s
DCO action / DCO (pull_request) Successful in 2m39s
Build / Build Components (1.21) (pull_request) Successful in 3m38s
Build / Build Components (1.20) (pull_request) Successful in 3m45s
Tests and linters / Staticcheck (pull_request) Successful in 4m15s
Tests and linters / Lint (pull_request) Successful in 5m47s
Tests and linters / Tests (1.20) (pull_request) Successful in 11m49s
Tests and linters / Tests (1.21) (pull_request) Successful in 12m16s
Tests and linters / Tests with -race (pull_request) Successful in 12m31s
Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
104 lines
2.2 KiB
Go
104 lines
2.2 KiB
Go
package blobovnicza
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
const (
|
|
dataSizeAndItemsCountBufLength = 8
|
|
)
|
|
|
|
var (
|
|
metaBucketName = []byte("META")
|
|
dataSizeKey = []byte("data_size")
|
|
itemsCountKey = []byte("items_count")
|
|
)
|
|
|
|
func isNonDataBucket(bucketName []byte) bool {
|
|
return bytes.Equal(bucketName, incompletedMoveBucketName) || bytes.Equal(bucketName, metaBucketName)
|
|
}
|
|
|
|
func hasDataSize(tx *bbolt.Tx) (uint64, bool) {
|
|
b := tx.Bucket(metaBucketName)
|
|
if b == nil {
|
|
return 0, false
|
|
}
|
|
v := b.Get(dataSizeKey)
|
|
if v == nil {
|
|
return 0, false
|
|
}
|
|
if len(v) != dataSizeAndItemsCountBufLength {
|
|
return 0, false
|
|
}
|
|
return binary.LittleEndian.Uint64(v), true
|
|
}
|
|
|
|
func hasItemsCount(tx *bbolt.Tx) (uint64, bool) {
|
|
b := tx.Bucket(metaBucketName)
|
|
if b == nil {
|
|
return 0, false
|
|
}
|
|
v := b.Get(itemsCountKey)
|
|
if v == nil {
|
|
return 0, false
|
|
}
|
|
if len(v) != dataSizeAndItemsCountBufLength {
|
|
return 0, false
|
|
}
|
|
return binary.LittleEndian.Uint64(v), true
|
|
}
|
|
|
|
func saveDataSize(tx *bbolt.Tx, size uint64) error {
|
|
b, err := tx.CreateBucketIfNotExists(metaBucketName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buf := make([]byte, dataSizeAndItemsCountBufLength)
|
|
binary.LittleEndian.PutUint64(buf, size)
|
|
return b.Put(dataSizeKey, buf)
|
|
}
|
|
|
|
func saveItemsCount(tx *bbolt.Tx, count uint64) error {
|
|
b, err := tx.CreateBucketIfNotExists(metaBucketName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buf := make([]byte, dataSizeAndItemsCountBufLength)
|
|
binary.LittleEndian.PutUint64(buf, count)
|
|
return b.Put(itemsCountKey, buf)
|
|
}
|
|
|
|
func updateMeta(tx *bbolt.Tx, updateValues func(count, size uint64) (uint64, uint64)) error {
|
|
b, err := tx.CreateBucketIfNotExists(metaBucketName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var count uint64
|
|
var size uint64
|
|
|
|
v := b.Get(itemsCountKey)
|
|
if v != nil {
|
|
count = binary.LittleEndian.Uint64(v)
|
|
}
|
|
|
|
v = b.Get(dataSizeKey)
|
|
if v != nil {
|
|
size = binary.LittleEndian.Uint64(v)
|
|
}
|
|
|
|
count, size = updateValues(count, size)
|
|
|
|
sizeBuf := make([]byte, dataSizeAndItemsCountBufLength)
|
|
binary.LittleEndian.PutUint64(sizeBuf, size)
|
|
if err := b.Put(dataSizeKey, sizeBuf); err != nil {
|
|
return err
|
|
}
|
|
|
|
countBuf := make([]byte, dataSizeAndItemsCountBufLength)
|
|
binary.LittleEndian.PutUint64(countBuf, count)
|
|
return b.Put(itemsCountKey, countBuf)
|
|
}
|