add staging cache to bolt tracking store

This commit is contained in:
vyzo 2021-07-04 06:34:26 +03:00
parent 642f0e4740
commit 00fcf6dd72

View File

@ -1,6 +1,7 @@
package splitstore package splitstore
import ( import (
"sync"
"time" "time"
"golang.org/x/xerrors" "golang.org/x/xerrors"
@ -9,6 +10,8 @@ import (
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
) )
const boltMarkSetStaging = 16384
type BoltMarkSetEnv struct { type BoltMarkSetEnv struct {
db *bolt.DB db *bolt.DB
} }
@ -18,6 +21,10 @@ var _ MarkSetEnv = (*BoltMarkSetEnv)(nil)
type BoltMarkSet struct { type BoltMarkSet struct {
db *bolt.DB db *bolt.DB
bucketId []byte bucketId []byte
// cache for batching
mx sync.RWMutex
pend map[string]struct{}
} }
var _ MarkSet = (*BoltMarkSet)(nil) var _ MarkSet = (*BoltMarkSet)(nil)
@ -49,7 +56,11 @@ func (e *BoltMarkSetEnv) Create(name string, hint int64) (MarkSet, error) {
return nil, err return nil, err
} }
return &BoltMarkSet{db: e.db, bucketId: bucketId}, nil return &BoltMarkSet{
db: e.db,
bucketId: bucketId,
pend: make(map[string]struct{}),
}, nil
} }
func (e *BoltMarkSetEnv) Close() error { func (e *BoltMarkSetEnv) Close() error {
@ -57,16 +68,48 @@ func (e *BoltMarkSetEnv) Close() error {
} }
func (s *BoltMarkSet) Mark(cid cid.Cid) error { func (s *BoltMarkSet) Mark(cid cid.Cid) error {
return s.db.Update(func(tx *bolt.Tx) 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) b := tx.Bucket(s.bucketId)
return b.Put(cid.Hash(), markBytes) 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) { 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 { err = s.db.View(func(tx *bolt.Tx) error {
b := tx.Bucket(s.bucketId) b := tx.Bucket(s.bucketId)
v := b.Get(cid.Hash()) v := b.Get(key)
result = v != nil result = v != nil
return nil return nil
}) })