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)
|
||
|
|
||
|
buf := make([]byte, dataSizeAndItemsCountBufLength)
|
||
|
binary.LittleEndian.PutUint64(buf, size)
|
||
|
if err := b.Put(dataSizeKey, buf); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
binary.LittleEndian.PutUint64(buf, count)
|
||
|
return b.Put(itemsCountKey, buf)
|
||
|
}
|