From 66ef7513f577397932a37b8c4bf6f86acddcff82 Mon Sep 17 00:00:00 2001 From: Cool Developer Date: Tue, 28 Feb 2023 08:48:42 -0500 Subject: [PATCH 1/3] add api to save changeset --- diff_test.go | 15 ++------------- mutable_tree.go | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/diff_test.go b/diff_test.go index 388f1f23e..66a55d054 100644 --- a/diff_test.go +++ b/diff_test.go @@ -21,19 +21,8 @@ func TestDiffRoundTrip(t *testing.T) { db := db.NewMemDB() tree, err := NewMutableTree(db, 0, true) require.NoError(t, err) - for _, cs := range changeSets { - for _, pair := range cs.Pairs { - if pair.Delete { - _, removed, err := tree.Remove(pair.Key) - require.True(t, removed) - require.NoError(t, err) - } else { - _, err := tree.Set(pair.Key, pair.Value) - require.NoError(t, err) - } - } - _, _, err := tree.SaveVersion() - require.NoError(t, err) + for i := range changeSets { + require.NoError(t, tree.SaveChangeSet(&changeSets[i])) } // extract change sets from db diff --git a/mutable_tree.go b/mutable_tree.go index 272acba7f..10803fd7b 100644 --- a/mutable_tree.go +++ b/mutable_tree.go @@ -1012,3 +1012,29 @@ func (tree *MutableTree) balance(node *Node) (newSelf *Node, err error) { // Nothing changed return node, nil } + +// SaveChangeSet saves a ChangeSet to the tree. +// It is used to replay a ChangeSet as a new version. +func (tree *MutableTree) SaveChangeSet(cs *ChangeSet) error { + // if the tree has uncommitted changes, return error + if tree.root != nil && !tree.root.persisted { + return fmt.Errorf("cannot save changeset with uncommitted changes") + } + for _, pair := range cs.Pairs { + if pair.Delete { + _, removed, err := tree.Remove(pair.Key) + if !removed { + return fmt.Errorf("attempted to remove non-existent key %s", pair.Key) + } + if err != nil { + return err + } + } else { + if _, err := tree.Set(pair.Key, pair.Value); err != nil { + return err + } + } + } + _, _, err := tree.SaveVersion() + return err +} From 1fed4b7dbdbf4dc62b438fcc94f73b2f58180d7a Mon Sep 17 00:00:00 2001 From: Cool Developer Date: Tue, 28 Feb 2023 08:54:55 -0500 Subject: [PATCH 2/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 881799984..0add0ae41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - [#636](https://github.com/cosmos/iavl/pull/636) Speed up rollback method: `LoadVersionForOverwriting`. - [#654](https://github.com/cosmos/iavl/pull/654) Add API `TraverseStateChanges` to extract state changes from iavl versions. - [#638](https://github.com/cosmos/iavl/pull/638) Make LazyLoadVersion check the opts.InitialVersion, add API `LazyLoadVersionForOverwriting`. +- [#695](https://github.com/cosmos/iavl/pull/695) Add API `SaveChangeSet` to save the changeset as a new version. ## 0.19.4 (October 28, 2022) From e8f47f5a1e3ba81cf86aa23fb3e2bb43003f9df3 Mon Sep 17 00:00:00 2001 From: Cool Developer Date: Thu, 2 Mar 2023 07:58:48 -0500 Subject: [PATCH 3/3] return the last version --- diff_test.go | 4 +++- mutable_tree.go | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/diff_test.go b/diff_test.go index 66a55d054..baa87c982 100644 --- a/diff_test.go +++ b/diff_test.go @@ -22,7 +22,9 @@ func TestDiffRoundTrip(t *testing.T) { tree, err := NewMutableTree(db, 0, true) require.NoError(t, err) for i := range changeSets { - require.NoError(t, tree.SaveChangeSet(&changeSets[i])) + v, err := tree.SaveChangeSet(&changeSets[i]) + require.NoError(t, err) + require.Equal(t, int64(i+1), v) } // extract change sets from db diff --git a/mutable_tree.go b/mutable_tree.go index 10803fd7b..ebfa457fa 100644 --- a/mutable_tree.go +++ b/mutable_tree.go @@ -1015,26 +1015,26 @@ func (tree *MutableTree) balance(node *Node) (newSelf *Node, err error) { // SaveChangeSet saves a ChangeSet to the tree. // It is used to replay a ChangeSet as a new version. -func (tree *MutableTree) SaveChangeSet(cs *ChangeSet) error { +func (tree *MutableTree) SaveChangeSet(cs *ChangeSet) (int64, error) { // if the tree has uncommitted changes, return error if tree.root != nil && !tree.root.persisted { - return fmt.Errorf("cannot save changeset with uncommitted changes") + return 0, fmt.Errorf("cannot save changeset with uncommitted changes") } for _, pair := range cs.Pairs { if pair.Delete { _, removed, err := tree.Remove(pair.Key) if !removed { - return fmt.Errorf("attempted to remove non-existent key %s", pair.Key) + return 0, fmt.Errorf("attempted to remove non-existent key %s", pair.Key) } if err != nil { - return err + return 0, err } } else { if _, err := tree.Set(pair.Key, pair.Value); err != nil { - return err + return 0, err } } } - _, _, err := tree.SaveVersion() - return err + _, version, err := tree.SaveVersion() + return version, err }