Skip to content

Commit

Permalink
Problem: export API not supported in memiavl (#924)
Browse files Browse the repository at this point in the history
* Problem: export API not supported in memiavl

* Update CHANGELOG.md

Signed-off-by: yihuang <huang@crypto.com>

---------

Signed-off-by: yihuang <huang@crypto.com>
  • Loading branch information
yihuang committed Mar 14, 2023
1 parent 72551d6 commit afc82ed
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

- [#890](https://github.com/crypto-org-chain/cronos/pull/890) optimize memiavl snapshot format.
- [#904](https://github.com/crypto-org-chain/cronos/pull/904) Enable "dynamic-level-bytes" on new `application.db`.
- [#924](https://github.com/crypto-org-chain/cronos/pull/924) memiavl support `Export` API.

*Feb 09, 2022*

Expand Down
31 changes: 31 additions & 0 deletions memiavl/export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package memiavl

import (
"github.com/cosmos/iavl"
)

type Exporter struct {
snapshot *Snapshot
i uint32
count int
}

func (e *Exporter) Next() (*iavl.ExportNode, error) {
if int(e.i) >= e.count {
return nil, iavl.ExportDone
}
node := e.snapshot.Node(e.i)
e.i++

height := node.Height()
var value []byte
if height == 0 {
value = node.Value()
}
return &iavl.ExportNode{
Height: int8(height),
Version: int64(node.Version()),
Key: node.Key(),
Value: value,
}, nil
}
5 changes: 5 additions & 0 deletions memiavl/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ func (snapshot *Snapshot) KeyValue(offset uint64) ([]byte, []byte) {
return key, value
}

// Export exports the nodes in DFS post-order, resemble the API of existing iavl library
func (snapshot *Snapshot) Export() *Exporter {
return &Exporter{snapshot: snapshot, count: snapshot.nodesLen()}
}

// WriteSnapshot save the IAVL tree to a new snapshot directory.
func (t *Tree) WriteSnapshot(snapshotDir string) (returnErr error) {
var rootIndex uint32
Expand Down
40 changes: 40 additions & 0 deletions memiavl/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package memiavl
import (
"testing"

"github.com/cosmos/iavl"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -45,3 +46,42 @@ func TestSnapshotEncodingRoundTrip(t *testing.T) {
require.Equal(t, len(ChangeSets), int(v))
require.NoError(t, snapshot.Close())
}

func TestSnapshotExport(t *testing.T) {
expNodes := []*iavl.ExportNode{
{Key: []byte("hello"), Value: []byte("world1"), Version: 2, Height: 0},
{Key: []byte("hello1"), Value: []byte("world1"), Version: 2, Height: 0},
{Key: []byte("hello1"), Value: nil, Version: 3, Height: 1},
{Key: []byte("hello2"), Value: []byte("world1"), Version: 3, Height: 0},
{Key: []byte("hello3"), Value: []byte("world1"), Version: 3, Height: 0},
{Key: []byte("hello3"), Value: nil, Version: 3, Height: 1},
{Key: []byte("hello2"), Value: nil, Version: 3, Height: 2},
}

// setup test tree
tree := NewEmptyTree(0)
for _, changes := range ChangeSets[:3] {
applyChangeSet(tree, changes)
_, _, err := tree.SaveVersion(true)
require.NoError(t, err)
}

snapshotDir := t.TempDir()
require.NoError(t, tree.WriteSnapshot(snapshotDir))

snapshot, err := OpenSnapshot(snapshotDir)
require.NoError(t, err)

var nodes []*iavl.ExportNode
exporter := snapshot.Export()
for {
node, err := exporter.Next()
if err == iavl.ExportDone {
break
}
require.NoError(t, err)
nodes = append(nodes, node)
}

require.Equal(t, expNodes, nodes)
}

0 comments on commit afc82ed

Please sign in to comment.