From b0666d637c20a38969bf1702b57fc379b9b07b67 Mon Sep 17 00:00:00 2001 From: Erik Grinaker Date: Wed, 26 Aug 2020 16:47:08 +0200 Subject: [PATCH] add MutableTree.SetInitialVersion() (#312) Requested in https://github.com/cosmos/cosmos-sdk/pull/7089#issuecomment-680877202. I didn't add a `GetInitialVersion()`, since it's not clear whether this should return only the option or the _actual_ initial version that exists in a tree. It might be cleaner to add `GetOptions()`, `SetOptions()`, and `UpdateOptions(func (o Options) Options)`, but we may not want all options to be mutable after construction. CC @amaurymartiny --- CHANGELOG.md | 6 +++++- mutable_tree.go | 7 +++++++ mutable_tree_test.go | 12 ++++++++++++ nodedb.go | 7 ++++--- options.go | 4 ++-- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87e046315..e0bede5c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,11 @@ ### Improvements -- Added `Options.InitialVersion` to specify the initial version to start new IAVL trees from. +- [\#299](https://github.com/cosmos/iavl/pull/299) Added `Options.InitialVersion` to specify the + initial version for new IAVL trees. + +- [\#312](https://github.com/cosmos/iavl/pull/312) Added `MutableTree.SetInitialVersion()` to + set the initial version after tree initialization. ## 0.14.0 (July 2, 2020) diff --git a/mutable_tree.go b/mutable_tree.go index 346683d6a..432172b96 100644 --- a/mutable_tree.go +++ b/mutable_tree.go @@ -523,6 +523,13 @@ func (tree *MutableTree) deleteVersion(version int64) error { return nil } +// SetInitialVersion sets the initial version of the tree, replacing Options.InitialVersion. +// It is only used during the initial SaveVersion() call for a tree with no other versions, +// and is otherwise ignored. +func (tree *MutableTree) SetInitialVersion(version uint64) { + tree.ndb.opts.InitialVersion = version +} + // DeleteVersions deletes a series of versions from the MutableTree. An error // is returned if any single version is invalid or the delete fails. All writes // happen in a single batch with a single commit. diff --git a/mutable_tree_test.go b/mutable_tree_test.go index c7c289f23..b88c4c76a 100644 --- a/mutable_tree_test.go +++ b/mutable_tree_test.go @@ -147,6 +147,18 @@ func TestMutableTree_InitialVersion(t *testing.T) { assert.EqualValues(t, 11, version) } +func TestMutableTree_SetInitialVersion(t *testing.T) { + memDB := db.NewMemDB() + tree, err := NewMutableTree(memDB, 0) + require.NoError(t, err) + tree.SetInitialVersion(9) + + tree.Set([]byte("a"), []byte{0x01}) + _, version, err := tree.SaveVersion() + require.NoError(t, err) + assert.EqualValues(t, 9, version) +} + func BenchmarkMutableTree_Set(b *testing.B) { db := db.NewDB("test", db.MemDBBackend, "") t, err := NewMutableTree(db, 100000) diff --git a/nodedb.go b/nodedb.go index 0162f79f2..2ec7806fe 100644 --- a/nodedb.go +++ b/nodedb.go @@ -38,7 +38,7 @@ type nodeDB struct { mtx sync.Mutex // Read/write lock. db dbm.DB // Persistent node storage. batch dbm.Batch // Batched writing buffer. - opts *Options // Options to customize for pruning/writing + opts Options // Options to customize for pruning/writing versionReaders map[int64]uint32 // Number of active version readers latestVersion int64 @@ -49,12 +49,13 @@ type nodeDB struct { func newNodeDB(db dbm.DB, cacheSize int, opts *Options) *nodeDB { if opts == nil { - opts = DefaultOptions() + o := DefaultOptions() + opts = &o } return &nodeDB{ db: db, batch: db.NewBatch(), - opts: opts, + opts: *opts, latestVersion: 0, // initially invalid nodeCache: make(map[string]*list.Element), nodeCacheSize: cacheSize, diff --git a/options.go b/options.go index 61c54740d..ba9410213 100644 --- a/options.go +++ b/options.go @@ -13,6 +13,6 @@ type Options struct { } // DefaultOptions returns the default options for IAVL. -func DefaultOptions() *Options { - return &Options{} +func DefaultOptions() Options { + return Options{} }