RIP bbolt-backed markset

This commit is contained in:
vyzo 2021-07-07 16:39:37 +03:00
parent 9dbb2e0abd
commit 451ddf50ab
4 changed files with 6 additions and 133 deletions

View File

@ -1,8 +1,6 @@
package splitstore
import (
"path/filepath"
"golang.org/x/xerrors"
cid "github.com/ipfs/go-cid"
@ -30,14 +28,12 @@ func OpenMarkSetEnv(path string, mtype string) (MarkSetEnv, error) {
switch mtype {
case "bloom":
return NewBloomMarkSetEnv(false)
case "bloomts":
case "bloomts": // thread-safe
return NewBloomMarkSetEnv(true)
case "map":
return NewMapMarkSetEnv(false)
case "mapts":
case "mapts": // thread-safe
return NewMapMarkSetEnv(true)
case "bolt":
return NewBoltMarkSetEnv(filepath.Join(path, "markset.bolt"))
default:
return nil, xerrors.Errorf("unknown mark set type %s", mtype)
}

View File

@ -1,124 +0,0 @@
package splitstore
import (
"sync"
"time"
"golang.org/x/xerrors"
cid "github.com/ipfs/go-cid"
bolt "go.etcd.io/bbolt"
)
const boltMarkSetStaging = 16384
type BoltMarkSetEnv struct {
db *bolt.DB
}
var _ MarkSetEnv = (*BoltMarkSetEnv)(nil)
type BoltMarkSet struct {
db *bolt.DB
bucketId []byte
// cache for batching
mx sync.RWMutex
pend map[string]struct{}
}
var _ MarkSet = (*BoltMarkSet)(nil)
func NewBoltMarkSetEnv(path string) (*BoltMarkSetEnv, error) {
db, err := bolt.Open(path, 0644,
&bolt.Options{
Timeout: 1 * time.Second,
NoSync: true,
})
if err != nil {
return nil, err
}
return &BoltMarkSetEnv{db: db}, nil
}
func (e *BoltMarkSetEnv) Create(name string, hint int64) (MarkSet, error) {
bucketId := []byte(name)
err := e.db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists(bucketId)
if err != nil {
return xerrors.Errorf("error creating bolt db bucket %s: %w", name, err)
}
return nil
})
if err != nil {
return nil, err
}
return &BoltMarkSet{
db: e.db,
bucketId: bucketId,
pend: make(map[string]struct{}),
}, nil
}
func (e *BoltMarkSetEnv) Close() error {
return e.db.Close()
}
func (s *BoltMarkSet) Mark(cid cid.Cid) error {
s.mx.Lock()
defer s.mx.Unlock()
key := cid.Hash()
s.pend[string(key)] = struct{}{}
if len(s.pend) < boltMarkSetStaging {
return nil
}
err := s.db.Batch(func(tx *bolt.Tx) error {
b := tx.Bucket(s.bucketId)
for key := range s.pend {
err := b.Put([]byte(key), markBytes)
if err != nil {
return err
}
}
return nil
})
if err != nil {
return err
}
s.pend = make(map[string]struct{})
return nil
}
func (s *BoltMarkSet) Has(cid cid.Cid) (result bool, err error) {
s.mx.RLock()
defer s.mx.RUnlock()
key := cid.Hash()
_, result = s.pend[string(key)]
if result {
return result, nil
}
err = s.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket(s.bucketId)
v := b.Get(key)
result = v != nil
return nil
})
return result, err
}
func (s *BoltMarkSet) Close() error {
return s.db.Update(func(tx *bolt.Tx) error {
return tx.DeleteBucket(s.bucketId)
})
}

View File

@ -8,8 +8,8 @@ import (
"github.com/multiformats/go-multihash"
)
func TestBoltMarkSet(t *testing.T) {
testMarkSet(t, "bolt")
func TestMapMarkSet(t *testing.T) {
testMarkSet(t, "map")
}
func TestBloomMarkSet(t *testing.T) {

View File

@ -92,7 +92,8 @@ const (
type Config struct {
// MarkSetType is the type of mark set to use.
//
// Sane values are: "mapts", "bolt" (if you are memory constrained).
// Only current sane value is "mapts", but we may add an option for a disk-backed
// markset for memory-constrained situations.
MarkSetType string
// DiscardColdBlocks indicates whether to skip moving cold blocks to the coldstore.