Skip to content

Commit

Permalink
change from map to btree
Browse files Browse the repository at this point in the history
  • Loading branch information
fredcarle committed Nov 17, 2022
1 parent 5c30e4f commit 802b146
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 37 deletions.
4 changes: 2 additions & 2 deletions datastore/memory/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ func (b *basicBatch) Commit(ctx context.Context) error {

for k, op := range b.ops {
if op.delete {
delete(b.target.values, k)
b.target.values.Delete(k.String())
} else {
b.target.values[k] = op.value
b.target.values.Set(k.String(), op.value)
}
}

Expand Down
37 changes: 18 additions & 19 deletions datastore/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ import (

ds "github.com/ipfs/go-datastore"
dsq "github.com/ipfs/go-datastore/query"
"github.com/tidwall/btree"
)

// Store uses a standard Go map for internal storage.
// Store uses a btree for internal storage.
type Store struct {
syncLock sync.Mutex
values map[ds.Key][]byte
values *btree.Map[string, []byte]
}

var _ ds.Datastore = (*Store)(nil)
Expand All @@ -31,7 +32,7 @@ var _ ds.TxnFeature = (*Store)(nil)
// NewStore constructs an empty Store.
func NewStore() (d *Store) {
return &Store{
values: make(map[ds.Key][]byte),
values: btree.NewMap[string, []byte](2),
}
}

Expand All @@ -48,8 +49,7 @@ func (d *Store) Close() error {
func (d *Store) Delete(ctx context.Context, key ds.Key) (err error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

delete(d.values, key)
d.values.Delete(key.String())
return nil
}

Expand All @@ -58,20 +58,19 @@ func (d *Store) Get(ctx context.Context, key ds.Key) (value []byte, err error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

val, found := d.values[key]
if !found {
return nil, ds.ErrNotFound
if val, exists := d.values.Get(key.String()); exists {
return val, nil
}
return val, nil
return nil, ds.ErrNotFound
}

// GetSize implements ds.GetSize
func (d *Store) GetSize(ctx context.Context, key ds.Key) (size int, err error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

if v, found := d.values[key]; found {
return len(v), nil
if val, exists := d.values.Get(key.String()); exists {
return len(val), nil
}
return -1, ds.ErrNotFound
}
Expand All @@ -81,8 +80,8 @@ func (d *Store) Has(ctx context.Context, key ds.Key) (exists bool, err error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

_, found := d.values[key]
return found, nil
_, exists = d.values.Get(key.String())
return exists, nil
}

// NewTransaction return a ds.Txn datastore based on Store
Expand All @@ -94,8 +93,7 @@ func (d *Store) NewTransaction(ctx context.Context, readOnly bool) (ds.Txn, erro
func (d *Store) Put(ctx context.Context, key ds.Key, value []byte) (err error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

d.values[key] = value
d.values.Set(key.String(), value)
return nil
}

Expand All @@ -104,11 +102,12 @@ func (d *Store) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) {
d.syncLock.Lock()
defer d.syncLock.Unlock()

re := make([]dsq.Entry, 0, len(d.values))
for k, v := range d.values {
e := dsq.Entry{Key: k.String(), Size: len(v)}
re := make([]dsq.Entry, 0, d.values.Len())
iter := d.values.Iter()
for iter.Next() {
e := dsq.Entry{Key: iter.Key(), Size: len(iter.Value())}
if !q.KeysOnly {
e.Value = v
e.Value = iter.Value()
}
re = append(re, e)
}
Expand Down
10 changes: 4 additions & 6 deletions datastore/memory/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,10 @@ var (
)

func newLoadedStore() *Store {
return &Store{
values: map[ds.Key][]byte{
testKey1: testValue1,
testKey2: testValue2,
},
}
s := NewStore()
s.values.Load(testKey1.String(), testValue1)
s.values.Load(testKey2.String(), testValue2)
return s
}

func TestNewStore(t *testing.T) {
Expand Down
21 changes: 11 additions & 10 deletions datastore/memory/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,25 +100,26 @@ func (t *basicTxn) Query(ctx context.Context, q dsq.Query) (dsq.Results, error)
defer t.target.syncLock.Unlock()

// best effort allocation
re := make([]dsq.Entry, 0, len(t.target.values)+len(t.ops))
re := make([]dsq.Entry, 0, t.target.values.Len()+len(t.ops))
handledOps := make(map[ds.Key]struct{})
for k, v := range t.target.values {
iter := t.target.values.Iter()
for iter.Next() {
e := dsq.Entry{}
if op, exists := t.ops[k]; exists {
handledOps[k] = struct{}{}
if op, exists := t.ops[ds.NewKey(iter.Key())]; exists {
handledOps[ds.NewKey(iter.Key())] = struct{}{}
if op.delete {
continue
}
e.Key = k.String()
e.Key = iter.Key()
e.Size = len(op.value)
if !q.KeysOnly {
e.Value = op.value
}
} else {
e.Key = k.String()
e.Size = len(v)
e.Key = iter.Key()
e.Size = len(iter.Value())
if !q.KeysOnly {
e.Value = v
e.Value = iter.Value()
}
}

Expand Down Expand Up @@ -179,9 +180,9 @@ func (t *basicTxn) Commit(ctx context.Context) error {

for k, op := range t.ops {
if op.delete {
delete(t.target.values, k)
t.target.values.Delete(k.String())
} else {
t.target.values[k] = op.value
t.target.values.Set(k.String(), op.value)
}
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ require (
github.com/spf13/viper v1.11.0
github.com/stretchr/testify v1.8.0
github.com/textileio/go-libp2p-pubsub-rpc v0.0.9
github.com/tidwall/btree v1.5.0
github.com/ugorji/go/codec v1.1.7
github.com/valyala/fastjson v1.6.3
go.uber.org/zap v1.23.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,8 @@ github.com/textileio/go-libp2p-pubsub-rpc v0.0.9 h1:yA58Giu0WYxS5+ixDTKDktMKcwWh
github.com/textileio/go-libp2p-pubsub-rpc v0.0.9/go.mod h1:3rOV6TxePSwADKpnwXBKpTjAA4QyjZBus13xc6VCtSw=
github.com/textileio/go-log/v2 v2.1.3-gke-2 h1:YkMA5ua0Cf/X6CkbexInsoJ/HdaHQBlgiv9Yy9hddNM=
github.com/textileio/go-log/v2 v2.1.3-gke-2/go.mod h1:DwACkjFS3kjZZR/4Spx3aPfSsciyslwUe5bxV8CEU2w=
github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ=
github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
Expand Down

0 comments on commit 802b146

Please sign in to comment.