Skip to content

Commit

Permalink
benchmark and test out "stackable" maps
Browse files Browse the repository at this point in the history
  • Loading branch information
thehowl committed Aug 21, 2024
1 parent 3e6bb61 commit 1347c5f
Show file tree
Hide file tree
Showing 3 changed files with 406 additions and 4 deletions.
4 changes: 4 additions & 0 deletions gno.land/cmd/gnoland/testdata/restart_missing_type.txtar
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# This txtar is a regression test for a bug, whereby a type is committed to
# the defaultStore.cacheTypes map, but not to the underlying store (due to a
# failing transaction).
# For more information: https://github.com/gnolang/gno/pull/2605
loadpkg gno.land/p/demo/avl
gnoland start

Expand Down
18 changes: 14 additions & 4 deletions gnovm/pkg/gnolang/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package gnolang

import (
"fmt"
"maps"
"reflect"
"slices"
"strconv"
Expand Down Expand Up @@ -114,6 +113,10 @@ type defaultStore struct {
opslog []StoreOp // for debugging and testing.
}

// bufferedTxMap is a wrapper around the map type, supporting regular Get, Set
// and Delete operations. Additionally, it can create a "buffered" version of
// itself, which will keep track of all write (set and delete) operations to the
// map; so that they can all be atomically committed when calling "write".
type bufferedTxMap[K comparable, V any] struct {
source map[K]V
dirty map[K]deletable[V]
Expand All @@ -131,7 +134,7 @@ func (b *bufferedTxMap[K, V]) init() {
// buffered creates a copy of b, which has a usable dirty map.
func (b bufferedTxMap[K, V]) buffered() bufferedTxMap[K, V] {
if b.dirty != nil {
panic("cannot stack buffered tx maps")
panic("cannot stack multiple bufferedTxMap")
}
return bufferedTxMap[K, V]{
source: b.source,
Expand Down Expand Up @@ -233,7 +236,7 @@ func (ds *defaultStore) BeginTransaction(baseStore, iavlStore store.Store) Trans

// transaction-scoped
parentStore: ds,
cacheObjects: maps.Clone(ds.cacheObjects),
cacheObjects: make(map[ObjectID]Object),
cacheTypes: ds.cacheTypes.buffered(),
cacheNodes: ds.cacheNodes.buffered(),
alloc: ds.alloc.Fork().Reset(),
Expand All @@ -249,11 +252,17 @@ func (ds *defaultStore) BeginTransaction(baseStore, iavlStore store.Store) Trans
current: nil,
opslog: nil,
}
ds2.SetCachePackage(Uverse())

return transactionStore{ds2}
}

func (ds *defaultStore) preprocessFork() Store {
// XXX IMPROVE
// XXX:
// This is only used internally, in Preprocess, when using evalStaticType
// and evalStaticTypeOfRaw.
// Could be joined with BeginTransaction if we allowed for stacking.

ds2 := &defaultStore{
// underlying stores
baseStore: ds.baseStore,
Expand All @@ -278,6 +287,7 @@ func (ds *defaultStore) preprocessFork() Store {
opslog: nil,
}
ds2.SetCachePackage(Uverse())

return ds2
}

Expand Down
Loading

0 comments on commit 1347c5f

Please sign in to comment.