implement bolt backed tracking store
This commit is contained in:
parent
b83994797a
commit
f1c61c4753
@ -1,7 +1,6 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
@ -22,5 +21,5 @@ func NewTrackingStore(path string, useLMDB bool) (TrackingStore, error) {
|
||||
return NewLMDBTrackingStore(filepath.Join(path, "snoop.lmdb"))
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("TODO: non-lmdb livesets")
|
||||
return NewBoltTrackingStore(filepath.Join(path, "snoop.bolt"))
|
||||
}
|
||||
|
102
chain/store/splitstore/snoop_bolt.go
Normal file
102
chain/store/splitstore/snoop_bolt.go
Normal file
@ -0,0 +1,102 @@
|
||||
package splitstore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
)
|
||||
|
||||
type BoltTrackingStore struct {
|
||||
db *bolt.DB
|
||||
bucketId []byte
|
||||
}
|
||||
|
||||
var _ TrackingStore = (*BoltTrackingStore)(nil)
|
||||
|
||||
func NewBoltTrackingStore(path string) (*BoltTrackingStore, error) {
|
||||
db, err := bolt.Open(path, 0644,
|
||||
&bolt.Options{
|
||||
Timeout: 1 * time.Second,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bucketId := []byte("snoop")
|
||||
err = db.Update(func(tx *bolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists(bucketId)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("error creating bolt db bucket %s: %w", string(bucketId), err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
db.Close() //nolint:errcheck
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BoltTrackingStore{db: db, bucketId: bucketId}, nil
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Put(cid cid.Cid, epoch abi.ChainEpoch) error {
|
||||
val := epochToBytes(epoch)
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.Put(cid.Hash(), val)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) PutBatch(cids []cid.Cid, epoch abi.ChainEpoch) error {
|
||||
val := epochToBytes(epoch)
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
for _, cid := range cids {
|
||||
err := b.Put(cid.Hash(), val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Get(cid cid.Cid) (epoch abi.ChainEpoch, err error) {
|
||||
err = s.db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
val := b.Get(cid.Hash())
|
||||
if val == nil {
|
||||
return xerrors.Errorf("missing tracking epoch for %s", cid)
|
||||
}
|
||||
epoch = bytesToEpoch(val)
|
||||
return nil
|
||||
})
|
||||
return epoch, err
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Delete(cid cid.Cid) error {
|
||||
return s.db.Batch(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.Delete(cid.Hash())
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) ForEach(f func(cid.Cid, abi.ChainEpoch) error) error {
|
||||
return s.db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket(s.bucketId)
|
||||
return b.ForEach(func(k, v []byte) error {
|
||||
cid := cid.NewCidV1(cid.Raw, k)
|
||||
epoch := bytesToEpoch(v)
|
||||
return f(cid, epoch)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *BoltTrackingStore) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
@ -20,7 +20,7 @@ type LMDBTrackingStore struct {
|
||||
|
||||
var _ TrackingStore = (*LMDBTrackingStore)(nil)
|
||||
|
||||
func NewLMDBTrackingStore(path string) (TrackingStore, error) {
|
||||
func NewLMDBTrackingStore(path string) (*LMDBTrackingStore, error) {
|
||||
env, err := lmdb.NewEnv()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to initialize LMDB env: %w", err)
|
||||
|
Loading…
Reference in New Issue
Block a user