Skip to content

Commit 670bbc1

Browse files
authored
[db] better fix for concurrent mapwrite by removing LRU cache from boltDB (iotexproject#2123)
1 parent 62c877e commit 670bbc1

File tree

4 files changed

+38
-45
lines changed

4 files changed

+38
-45
lines changed

db/counting_index.go

+13-10
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,7 @@ func NewCountingIndexNX(kv KVStore, name []byte) (CountingIndex, error) {
7474
}
7575
total = ZeroIndex
7676
}
77-
if kvFillPercent, ok := kv.(KVStoreWithBucketFillPercent); ok {
78-
if err := kvFillPercent.SetBucketFillPercent(bucket, 1.0); err != nil {
79-
// set an aggressive fill percent
80-
// b/c counting index only appends, further inserts to the bucket would never split the page
81-
return nil, err
82-
}
83-
}
77+
8478
return &countingIndex{
8579
kvStore: kvRange,
8680
bucket: bucket,
@@ -123,7 +117,7 @@ func (c *countingIndex) Add(value []byte, inBatch bool) error {
123117
b := batch.NewBatch()
124118
b.Put(c.bucket, byteutil.Uint64ToBytesBigEndian(c.size), value, "failed to add %d-th item", c.size+1)
125119
b.Put(c.bucket, CountKey, byteutil.Uint64ToBytesBigEndian(c.size+1), "failed to update size = %d", c.size+1)
126-
if err := c.kvStore.WriteBatch(b); err != nil {
120+
if err := c.commit(b); err != nil {
127121
return err
128122
}
129123
c.size++
@@ -170,7 +164,7 @@ func (c *countingIndex) Revert(count uint64) error {
170164
b.Delete(c.bucket, byteutil.Uint64ToBytesBigEndian(start+i), "failed to delete %d-th item", start+i)
171165
}
172166
b.Put(c.bucket, CountKey, byteutil.Uint64ToBytesBigEndian(start), "failed to update size = %d", start)
173-
if err := c.kvStore.WriteBatch(b); err != nil {
167+
if err := c.commit(b); err != nil {
174168
return err
175169
}
176170
c.size = start
@@ -190,9 +184,18 @@ func (c *countingIndex) Commit() error {
190184
return nil
191185
}
192186
c.batch.Put(c.bucket, CountKey, byteutil.Uint64ToBytesBigEndian(c.size), "failed to update size = %d", c.size)
193-
if err := c.kvStore.WriteBatch(c.batch); err != nil {
187+
if err := c.commit(c.batch); err != nil {
194188
return err
195189
}
196190
c.batch = nil
197191
return nil
198192
}
193+
194+
func (c *countingIndex) commit(b batch.KVStoreBatch) error {
195+
if kvFillPercent, ok := c.kvStore.(KVStoreWithBucketFillPercent); ok {
196+
// set an aggressive fill percent
197+
// b/c counting index only appends, further inserts to the bucket would never split the page
198+
return kvFillPercent.WriteBatchWithFillPercent(b, 1.0)
199+
}
200+
return c.kvStore.WriteBatch(b)
201+
}

db/db_bolt.go

+17-27
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"bytes"
1111
"context"
1212

13-
"github.com/iotexproject/go-pkgs/cache"
1413
"github.com/pkg/errors"
1514
bolt "go.etcd.io/bbolt"
1615

@@ -23,19 +22,17 @@ const fileMode = 0600
2322

2423
// boltDB is KVStore implementation based bolt DB
2524
type boltDB struct {
26-
db *bolt.DB
27-
path string
28-
config config.DB
29-
fillPercent *cache.ThreadSafeLruCache // specific fill percent for certain buckets (for example, 1.0 for append-only)
25+
db *bolt.DB
26+
path string
27+
config config.DB
3028
}
3129

3230
// NewBoltDB instantiates an BoltDB with implements KVStore
3331
func NewBoltDB(cfg config.DB) KVStoreWithBucketFillPercent {
3432
return &boltDB{
35-
db: nil,
36-
path: cfg.DbPath,
37-
config: cfg,
38-
fillPercent: cache.NewThreadSafeLruCache(256),
33+
db: nil,
34+
path: cfg.DbPath,
35+
config: cfg,
3936
}
4037
}
4138

@@ -67,9 +64,6 @@ func (b *boltDB) Put(namespace string, key, value []byte) (err error) {
6764
if err != nil {
6865
return err
6966
}
70-
if p, ok := b.getBucketFillPercent(namespace); ok {
71-
bucket.FillPercent = p
72-
}
7367
return bucket.Put(key, value)
7468
}); err == nil {
7569
break
@@ -257,6 +251,15 @@ func (b *boltDB) Delete(namespace string, key []byte) (err error) {
257251

258252
// WriteBatch commits a batch
259253
func (b *boltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
254+
return b.writeBatch(kvsb, 0.0)
255+
}
256+
257+
// WriteBatchWithFillPercent commits a batch with specified fill percent
258+
func (b *boltDB) WriteBatchWithFillPercent(kvsb batch.KVStoreBatch, percent float64) (err error) {
259+
return b.writeBatch(kvsb, percent)
260+
}
261+
262+
func (b *boltDB) writeBatch(kvsb batch.KVStoreBatch, percent float64) (err error) {
260263
succeed := true
261264
kvsb.Lock()
262265
defer func() {
@@ -283,8 +286,8 @@ func (b *boltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
283286
if e != nil {
284287
return errors.Wrapf(e, errFmt, errArgs)
285288
}
286-
if p, ok := b.getBucketFillPercent(ns); ok {
287-
bucket.FillPercent = p
289+
if percent != 0.0 {
290+
bucket.FillPercent = percent
288291
}
289292
if e := bucket.Put(write.Key(), write.Value()); e != nil {
290293
return errors.Wrapf(e, errFmt, errArgs)
@@ -312,19 +315,6 @@ func (b *boltDB) WriteBatch(kvsb batch.KVStoreBatch) (err error) {
312315
return err
313316
}
314317

315-
// SetBucketFillPercent sets specified fill percent for a bucket
316-
func (b *boltDB) SetBucketFillPercent(namespace string, percent float64) error {
317-
b.fillPercent.Add(namespace, percent)
318-
return nil
319-
}
320-
321-
func (b *boltDB) getBucketFillPercent(namespace string) (float64, bool) {
322-
if p, hit := b.fillPercent.Get(namespace); hit {
323-
return p.(float64), true
324-
}
325-
return 0, false
326-
}
327-
328318
// ======================================
329319
// below functions used by RangeIndex
330320
// ======================================

db/kvstore.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ type (
4747
// KVStoreWithBucketFillPercent is KVStore with option to set bucket fill percent
4848
KVStoreWithBucketFillPercent interface {
4949
KVStore
50-
// SetBucketFillPercent sets specified fill percent for a bucket
51-
SetBucketFillPercent(string, float64) error
50+
// WriteBatchWithFillPercent
51+
WriteBatchWithFillPercent(batch.KVStoreBatch, float64) error
5252
}
5353

5454
// KVStoreForRangeIndex is KVStore for range index

db/mock_kvstore.go

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)