forked from TrueCloudLab/frostfs-node
105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
// Package bbolt provides a kvio.Repository backed by bbolt.
|
|
package bbolt
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/kvio"
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
type impl struct {
|
|
db *bbolt.DB
|
|
}
|
|
|
|
type Options struct {
|
|
bbolt.Options
|
|
MaxBatchSize int
|
|
MaxBatchDelay time.Duration
|
|
}
|
|
|
|
var (
|
|
defaultBucket = []byte{0}
|
|
|
|
// ErrNoDefaultBucket is returned when the default bucket for objects is missing.
|
|
ErrNoDefaultBucket = errors.New("no default bucket")
|
|
)
|
|
|
|
func Open(path string, opts *Options) (kvio.Repository, error) {
|
|
db, err := bbolt.Open(path, os.ModePerm, &opts.Options)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not open database: %w", err)
|
|
}
|
|
|
|
if opts.MaxBatchSize > 0 {
|
|
db.MaxBatchSize = opts.MaxBatchSize
|
|
}
|
|
if opts.MaxBatchDelay > 0 {
|
|
db.MaxBatchDelay = opts.MaxBatchDelay
|
|
}
|
|
|
|
if !opts.Options.ReadOnly {
|
|
err = db.Update(func(tx *bbolt.Tx) error {
|
|
_, err := tx.CreateBucketIfNotExists(defaultBucket)
|
|
return err
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not create default bucket: %w", err)
|
|
}
|
|
}
|
|
|
|
return impl{db}, nil
|
|
}
|
|
|
|
func (r impl) Read(f func(kvio.ReadOnlyTx) error) error {
|
|
return r.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
if b == nil {
|
|
return ErrNoDefaultBucket
|
|
}
|
|
return f(txImpl{b, tx})
|
|
})
|
|
}
|
|
|
|
func (r impl) Write(f func(kvio.WriteOnlyTx) error) error {
|
|
return r.db.Batch(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
if b == nil {
|
|
return ErrNoDefaultBucket
|
|
}
|
|
return f(txImpl{b, tx})
|
|
})
|
|
}
|
|
|
|
func (r impl) ReadWrite(f func(kvio.ReadWriteTx) error) error {
|
|
return r.db.Update(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
if b == nil {
|
|
return ErrNoDefaultBucket
|
|
}
|
|
return f(txImpl{b, tx})
|
|
})
|
|
}
|
|
|
|
func (r impl) Stats() (kvio.Stats, error) {
|
|
var keyCount uint64
|
|
err := r.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(defaultBucket)
|
|
if b != nil {
|
|
keyCount = uint64(b.Stats().KeyN)
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return kvio.Stats{}, fmt.Errorf("could not read write-cache DB counter: %w", err)
|
|
}
|
|
|
|
return kvio.Stats{
|
|
KeyCount: keyCount,
|
|
}, nil
|
|
}
|
|
|
|
func (r impl) Close() error { return r.db.Close() }
|