Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PERFORMANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Some links for thought:

## Backend implementation

Storing each link in the tree in leveldb treats each node as an isolated item. Since we know some usage patterns (when a parent is hit, very likely one child will be hit), we could try to organize the memory and disk location of the nodes ourselves to make it more efficient. Or course, this could be a long, slippery slope.
Storing each link in the tree in leveldb treats each node as an isolated item. Since we know some usage patterns (when a parent is hit, very likely one child will be hit), we could try to organize the memory and disk location of the nodes ourselves to make it more efficient. Of course, this could be a long, slippery slope.

Inspired by the [Array representation](http://www.cse.hut.fi/en/research/SVG/TRAKLA2/tutorials/heap_tutorial/taulukkona.html) link above, we could consider other layouts for the nodes. For example, rather than store them alone, or the entire tree in one big array, the nodes could be placed in groups of 15 based on the parent (parent and 3 generations of children). Then we have 4 levels before jumping to another location. Maybe we just store this larger chunk as one leveldb location, or really try to do the mmap ourselves...

Expand Down
2 changes: 1 addition & 1 deletion cmd/legacydump/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It takes 5 arguments:
- dbtype: the type of database to use.
- dbdir: the directory to store the database.
- `random` or `sequential`: The `sequential` option will generate the tree from `1` to `version` in order and delete versions from `1` to `removal version`. The `random` option will delete `removal version` versions randomly.
- version: the upto number of versions to generate.
- version: the number of versions to generate.
- removal version: the number of versions to remove.

```shell
Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/adr-002-api-cleanup.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ DRAFT

## Abstract

This ADR proposes a cleanup of the API to make more understandable and maintainable the codebase of `iavl`.
This ADR proposes a cleanup of the API to make the `iavl` codebase more understandable and maintainable.

There is a lot of legacy code in the SDK that is not used anymore and can be removed. See the [Discussion](https://github.com/cosmos/iavl/issues/737) for more details.

There are some proposals for the speedup of the `Commit` by the async writes. See the [Discussion](https://github.com/cosmos/cosmos-sdk/issues/16173) for more details.
There are some proposals to speed up the `Commit` with async writes. See the [Discussion](https://github.com/cosmos/cosmos-sdk/issues/16173) for more details.

## Context

Expand Down
4 changes: 2 additions & 2 deletions docs/node/nodedb.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ It marshals and saves any new node that has been created under: `n|node.nodeKey.

### Deleting Versions

When a version `v` is deleted, all nodes which removed in the current version will be safely deleted and uncached from the storage. `nodeDB` will keep the range of versions [`fromVersion`, `toVersion`]. There are two apis to delete versions:
When a version `v` is deleted, all nodes which were removed in the current version will be safely deleted and uncached from the storage. `nodeDB` will keep the range of versions [`fromVersion`, `toVersion`]. There are two APIs to delete versions:

#### DeleteVersionsFrom

Expand Down Expand Up @@ -114,7 +114,7 @@ func (ndb *nodeDB) deleteVersion(version int64) error {
The traverseOrphans algorithm is shown below:

```golang
// traverseOrphans traverses orphans which removed by the updates of the version (n+1).
// traverseOrphans traverses orphans that were removed by the updates of the version (n+1).
func (ndb *nodeDB) traverseOrphans(version int64, fn func(*Node) error) error {
curKey, err := ndb.GetRoot(version + 1)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ Nodes of this tree are immutable and indexed by their hash. Thus any node serve

In an AVL tree, the heights of the two child subtrees of any node differ by at most one. Whenever this condition is violated upon an update, the tree is rebalanced by creating O(log(n)) new nodes that point to unmodified nodes of the old tree. In the original AVL algorithm, inner nodes can also hold key-value pairs. The AVL+ algorithm (note the plus) modifies the AVL algorithm to keep all values on leaf nodes, while only using branch-nodes to store keys. This simplifies the algorithm while keeping the merkle hash trail short.

The IAVL tree will typically be wrapped by a `MutableTree` to enable updates to the tree. Any changes between versions get persisted to disk while nodes that exist in both the old version and new version are simply pointed to by the respective tree without duplicated the node data.
The IAVL tree will typically be wrapped by a `MutableTree` to enable updates to the tree. Any changes between versions get persisted to disk while nodes that exist in both the old version and new version are simply pointed to by the respective tree without duplicating the node data.

When a node is no longer part of the latest IAVL tree, it is called an orphan. The orphaned node will exist in the nodeDB so long as there are versioned IAVL trees that are persisted in nodeDB that contain the orphaned node. Once all trees that referred to orphaned node have been deleted from database, the orphaned node will also get deleted.
When a node is no longer part of the latest IAVL tree, it is called an orphan. The orphaned node will exist in the nodeDB so long as there are versioned IAVL trees that are persisted in nodeDB that contain the orphaned node. Once all trees that referred to the orphaned node have been deleted from the database, the orphaned node will also get deleted.

In Ethereum, the analog is [Patricia tries](http://en.wikipedia.org/wiki/Radix_tree). There are tradeoffs. Keys do not need to be hashed prior to insertion in IAVL+ trees, so this provides faster iteration in the key space which may benefit some applications. The logic is simpler to implement, requiring only two types of nodes -- inner nodes and leaf nodes. On the other hand, while IAVL+ trees provide a deterministic merkle root hash, it depends on the order of transactions. In practice this shouldn't be a problem, since you can efficiently encode the tree structure when serializing the tree contents.

Expand Down Expand Up @@ -39,4 +39,4 @@ In Ethereum, the analog is [Patricia tries](http://en.wikipedia.org/wiki/Radix_t
7. [Export/import docs](./tree/export_import.md)
- Explains the overall export/import functionality
- Explains the `ExportNode` format for exported nodes
- Explains the algorithms for exporting and importing nodes
- Explains the algorithms for exporting and importing nodes
4 changes: 2 additions & 2 deletions docs/tree/immutable_tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (t *ImmutableTree) GetWithIndex(key []byte) (int64, []byte, error) {
}
```

Get by index will return both the key and the value. The index is the index in the list of leaf nodes sorted lexicographically by key. The leftmost leaf has index 0. It's neighbor has index 1 and so on.
Get by index will return both the key and the value. The index is the index in the list of leaf nodes sorted lexicographically by key. The leftmost leaf has index 0. Its neighbor has index 1 and so on.

```golang
// GetByIndex gets the key and value at the specified index.
Expand All @@ -54,7 +54,7 @@ Thus the callback is useful both as a way to run some logic on every key-value p

The `IterateRange` functions allow users to iterate over a specific range and specify if the iteration should be in ascending or descending order.

The API's for Iteration functions are shown below.
The APIs for iteration functions are shown below.

```golang
// Iterate iterates over all keys of the tree, in order.
Expand Down
2 changes: 1 addition & 1 deletion docs/tree/mutable_tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ After each set, the current working tree has its height and size recalculated. I

### Remove

Remove is another recursive function to remove a key-value pair from the IAVL pair. If the key that is trying to be removed does not exist, Remove is a no-op.
Remove is another recursive function to remove a key-value pair from the IAVL tree. If the key that is trying to be removed does not exist, Remove is a no-op.

Remove recurses down the IAVL tree in the same way that Set does until it reaches a leaf node. If the leaf node's key is equal to the remove key, the node is removed, and all of its parents are recursively updated. If not, the remove call does nothing.

Expand Down
2 changes: 1 addition & 1 deletion immutable_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (t *ImmutableTree) Export() (*Exporter, error) {
// IAVL.
//
// The index is the index in the list of leaf nodes sorted lexicographically by key. The leftmost leaf has index 0.
// It's neighbor has index 1 and so on.
// Its neighbor has index 1 and so on.
func (t *ImmutableTree) GetWithIndex(key []byte) (int64, []byte, error) {
if t.root == nil {
return 0, nil, nil
Expand Down
2 changes: 1 addition & 1 deletion mutable_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ func (tree *MutableTree) SetInitialVersion(version uint64) {
tree.initialVersionSet = true
}

// DeleteVersionsTo removes versions upto the given version from the MutableTree.
// DeleteVersionsTo removes versions up to the given version from the MutableTree.
// It will not block the SaveVersion() call, instead it will be queued and executed deferred.
func (tree *MutableTree) DeleteVersionsTo(toVersion int64) error {
if err := tree.ndb.DeleteVersionsTo(toVersion); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion node.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ func (node *Node) has(t *ImmutableTree, key []byte) (has bool, err error) {
// Get a key under the node.
//
// The index is the index in the list of leaf nodes sorted lexicographically by key. The leftmost leaf has index 0.
// It's neighbor has index 1 and so on.
// Its neighbor has index 1 and so on.
func (node *Node) get(t *ImmutableTree, key []byte) (index int64, value []byte, err error) {
if node.isLeaf() {
switch bytes.Compare(node.key, key) {
Expand Down
2 changes: 1 addition & 1 deletion nodedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1152,7 +1152,7 @@ func isReferenceRoot(bz []byte) (bool, int) {
return false, 0
}

// traverseOrphans traverses orphans which removed by the updates of the curVersion in the prevVersion.
// traverseOrphans traverses orphans that were removed by the updates of the curVersion in the prevVersion.
// NOTE: it is used for both legacy and new nodes.
func (ndb *nodeDB) traverseOrphans(prevVersion, curVersion int64, fn func(*Node) error) error {
cache := newRootkeyCache()
Expand Down
Loading