Skip to content

Commit

Permalink
feat: speed up rollback command
Browse files Browse the repository at this point in the history
- fully rebuild fast node indexes after rollback, rather than leave it in dirty state.
- skip unnecessary subtree traversal when deleting the latest version.
- restrict the iteration range when deleting orphans.
  • Loading branch information
yihuang committed Dec 8, 2022
1 parent e144f08 commit 85ae144
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 35 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

- [#586](https://github.com/cosmos/iavl/pull/586) Remove the `RangeProof` and refactor the ics23_proof to use the internal methods.
- [#640](https://github.com/cosmos/iavl/pull/640) commit `NodeDB` batch in `LoadVersionForOverwriting`.
- [#636](https://github.com/cosmos/iavl/pull/636) Speed up rollback method: `LoadVersionForOverwriting`.

## 0.19.4 (October 28, 2022)

Expand Down
19 changes: 7 additions & 12 deletions mutable_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,17 +632,18 @@ func (tree *MutableTree) LoadVersionForOverwriting(targetVersion int64) (int64,
return latestVersion, err
}

tree.mtx.Lock()
defer tree.mtx.Unlock()

tree.ndb.resetLatestVersion(latestVersion)

if !tree.skipFastStorageUpgrade {
if err := tree.enableFastStorageAndCommitLocked(); err != nil {
// it'll repopulates the fast node index because of version mismatch.
if _, err := tree.enableFastStorageAndCommitIfNotEnabled(); err != nil {
return latestVersion, err
}
}

tree.ndb.resetLatestVersion(latestVersion)

tree.mtx.Lock()
defer tree.mtx.Unlock()

for v := range tree.versions {
if v > targetVersion {
delete(tree.versions, v)
Expand Down Expand Up @@ -708,12 +709,6 @@ func (tree *MutableTree) enableFastStorageAndCommitIfNotEnabled() (bool, error)
return true, nil
}

func (tree *MutableTree) enableFastStorageAndCommitLocked() error {
tree.mtx.Lock()
defer tree.mtx.Unlock()
return tree.enableFastStorageAndCommit()
}

func (tree *MutableTree) enableFastStorageAndCommit() error {
var err error

Expand Down
34 changes: 11 additions & 23 deletions nodedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
defaultStorageVersionValue = "1.0.0"
fastStorageVersionValue = "1.1.0"
fastNodeCacheSize = 100000
maxVersion = int64(math.MaxInt64)
)

var (
Expand Down Expand Up @@ -452,7 +453,7 @@ func (ndb *nodeDB) DeleteVersionsFrom(version int64) error {
// Next, delete orphans:
// - Delete orphan entries *and referred nodes* with fromVersion >= version
// - Delete orphan entries with toVersion >= version-1 (since orphans at latest are not orphans)
err = ndb.traverseOrphans(func(key, hash []byte) error {
err = ndb.traverseRange(orphanKeyFormat.Key(version-1), orphanKeyFormat.Key(maxVersion), func(key, hash []byte) error {
var fromVersion, toVersion int64
orphanKeyFormat.Scan(key, &toVersion, &fromVersion)

Expand All @@ -477,7 +478,7 @@ func (ndb *nodeDB) DeleteVersionsFrom(version int64) error {
}

// Delete the version root entries
err = ndb.traverseRange(rootKeyFormat.Key(version), rootKeyFormat.Key(int64(math.MaxInt64)), func(k, v []byte) error {
err = ndb.traverseRange(rootKeyFormat.Key(version), rootKeyFormat.Key(maxVersion), func(k, v []byte) error {
if err = ndb.batch.Delete(k); err != nil {
return err
}
Expand All @@ -488,26 +489,7 @@ func (ndb *nodeDB) DeleteVersionsFrom(version int64) error {
return err
}

// Delete fast node entries
err = ndb.traverseFastNodes(func(keyWithPrefix, v []byte) error {
key := keyWithPrefix[1:]
fastNode, err := fastnode.DeserializeNode(key, v)
if err != nil {
return err
}

if version <= fastNode.GetVersionLastUpdatedAt() {
if err = ndb.batch.Delete(keyWithPrefix); err != nil {
return err
}
ndb.fastNodeCache.Remove(key)
}
return nil
})

if err != nil {
return err
}
// NOTICE: we don't touch fast node indexes here, because it'll be rebuilt later because of version mismatch.

return nil
}
Expand Down Expand Up @@ -605,6 +587,11 @@ func (ndb *nodeDB) deleteNodesFrom(version int64, hash []byte) error {
return err
}

if node.version < version {
// We can skip the whole sub-tree since children.version <= parent.version.
return nil
}

if node.leftHash != nil {
if err := ndb.deleteNodesFrom(version, node.leftHash); err != nil {
return err
Expand Down Expand Up @@ -725,7 +712,7 @@ func (ndb *nodeDB) rootKey(version int64) []byte {
func (ndb *nodeDB) getLatestVersion() (int64, error) {
if ndb.latestVersion == 0 {
var err error
ndb.latestVersion, err = ndb.getPreviousVersion(1<<63 - 1)
ndb.latestVersion, err = ndb.getPreviousVersion(maxVersion)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -789,6 +776,7 @@ func (ndb *nodeDB) traverseOrphans(fn func(keyWithPrefix, v []byte) error) error
}

// Traverse fast nodes and return error if any, nil otherwise
// nolint: unused
func (ndb *nodeDB) traverseFastNodes(fn func(k, v []byte) error) error {
return ndb.traversePrefix(fastKeyFormat.Key(), fn)
}
Expand Down

0 comments on commit 85ae144

Please sign in to comment.