Transaction
0397D0D44CF865…55A2F9064C2E
Block 352,822 · index 0 · indexed
Summary
- Hash
- 0397D0D44CF8651E5700008D0C8BB73FE4BCD6A4F5402BBCA7EF55A2F9064C2E
- Block
- 352,822
- Size
- 11529 bytes
- Gas used
- 16,619,621 / 21,605,559
- Fee
- 21606 ugnot
- Status
- success
Messages
- Attached funds
- 2000000 ugnot
Arguments · 9
- #1avl
- #2gnomod.toml
- #3module = "gno.land/p/g1wx60nkcp5lfsxmedeg7sfs47tzxkath05u63t4/avl" gno = "0.9"
- #4node.gno
- #5package avl type Node struct { key string // key is the unique identifier for the node. value any // value is the data stored in the node. height int8 // height is the height of the node in the tree. size int // size is the number of leaf nodes (key-value pairs) in the subtree rooted at this node. leftNode *Node // leftNode is the left child of the node. rightNode *Node // rightNode is the right child of the node. } func NewNode(key string, value any) *Node { return &Node{ key: key, value: value, height: 0, size: 1, } } func (node *Node) Size() int { if node == nil { return 0 } return node.size } func (node *Node) IsLeaf() bool { return node.height == 0 } func (node *Node) Key() string { return node.key } func (node *Node) Value() any { return node.value } func (node *Node) _copy() *Node { if node.height == 0 { panic("Why are you copying a value node?") } return &Node{ key: node.key, height: node.height, size: node.size, leftNode: node.leftNode, rightNode: node.rightNode, } } func (node *Node) Has(key string) (has bool) { if node == nil { return false } if node.key == key { return true } if node.height == 0 { return false } else { if key < node.key { return node.getLeftNode().Has(key) } else { return node.getRightNode().Has(key) } } } func (node *Node) Get(key string) (index int, value any, exists bool) { if node == nil { return 0, nil, false } if node.height == 0 { if node.key == key { return 0, node.value, true } else if node.key < key { return 1, nil, false } else { return 0, nil, false } } else { if key < node.key { return node.getLeftNode().Get(key) } else { rightNode := node.getRightNode() index, value, exists = rightNode.Get(key) index += node.size - rightNode.size return index, value, exists } } } func (node *Node) GetByIndex(index int) (key string, value any) { if index < 0 { panic("GetByIndex: negative index not allowed") } if node.height == 0 { if index != 0 { panic("GetByIndex asked for invalid index") } return node.key, node.value } else { leftNode := node.getLeftNode() if index < leftNode.size { return leftNode.GetByIndex(index) } else { return node.getRightNode().GetByIndex(index - leftNode.size) } } } func (node *Node) Set(key string, value any) (newSelf *Node, updated bool) { if node == nil { return NewNode(key, value), false } if node.height == 0 { if key < node.key { return &Node{ key: node.key, height: 1, size: 2, leftNode: NewNode(key, value), rightNode: node, }, false } else if key == node.key { return NewNode(key, value), true } else { return &Node{ key: key, height: 1, size: 2, leftNode: node, rightNode: NewNode(key, value), }, false } } else { node = node._copy() if key < node.key { node.leftNode, updated = node.getLeftNode().Set(key, value) } else { node.rightNode, updated = node.getRightNode().Set(key, value) } if updated { return node, updated } else { node.calcHeightAndSize() return node.balance(), updated } } } func (node *Node) Remove(key string) ( newNode *Node, newKey string, value any, removed bool, ) { if node == nil { return nil, "", nil, false } if node.height == 0 { if key == node.key { return nil, "", node.value, true } else { return node, "", nil, false } } else { if key < node.key { var newLeftNode *Node newLeftNode, newKey, value, removed = node.getLeftNode().Remove(key) if !removed { return node, "", value, false } else if newLeftNode == nil { // left node held value, was removed return node.rightNode, node.key, value, true } node = node._copy() node.leftNode = newLeftNode node.calcHeightAndSize() node = node.balance() return node, newKey, value, true } else { var newRightNode *Node newRightNode, newKey, value, removed = node.getRightNode().Remove(key) if !removed { return node, "", value, false } else if newRightNode == nil { // right node held value, was removed return node.leftNode, "", value, true } node = node._copy() node.rightNode = newRightNode if newKey != "" { node.key = newKey } node.calcHeightAndSize() node = node.balance() return node, "", value, true } } } func (node *Node) getLeftNode() *Node { return node.leftNode } func (node *Node) getRightNode() *Node { return node.rightNode } func (node *Node) rotateRight() *Node { node = node._copy() l := node.getLeftNode() _l := l._copy() _lrCached := _l.rightNode _l.rightNode = node node.leftNode = _lrCached node.calcHeightAndSize() _l.calcHeightAndSize() return _l } func (node *Node) rotateLeft() *Node { node = node._copy() r := node.getRightNode() _r := r._copy() _rlCached := _r.leftNode _r.leftNode = node node.rightNode = _rlCached node.calcHeightAndSize() _r.calcHeightAndSize() return _r } func (node *Node) calcHeightAndSize() { node.height = maxInt8(node.getLeftNode().height, node.getRightNode().height) + 1 node.size = node.getLeftNode().size + node.getRightNode().size } func (node *Node) calcBalance() int { return int(node.getLeftNode().height) - int(node.getRightNode().height) } func (node *Node) balance() (newSelf *Node) { balance := node.calcBalance() if balance > 1 { if node.getLeftNode().calcBalance() >= 0 { return node.rotateRight() } else { left := node.getLeftNode() node.leftNode = left.rotateLeft() return node.rotateRight() } } if balance < -1 { if node.getRightNode().calcBalance() <= 0 { return node.rotateLeft() } else { right := node.getRightNode() node.rightNode = right.rotateRight() return node.rotateLeft() } } return node } func (node *Node) Iterate(start, end string, cb func(*Node) bool) bool { return node.TraverseInRange(start, end, true, true, cb) } func (node *Node) ReverseIterate(start, end string, cb func(*Node) bool) bool { return node.TraverseInRange(start, end, false, true, cb) } func (node *Node) TraverseInRange(start, end string, ascending bool, leavesOnly bool, cb func(*Node) bool) bool { if node == nil { return false } afterStart := (start == "" || start < node.key) startOrAfter := (start == "" || start <= node.key) beforeEnd := false if ascending { beforeEnd = (end == "" || node.key < end) } else { beforeEnd = (end == "" || node.key <= end) } stop := false if (!node.IsLeaf() && !leavesOnly) || (node.IsLeaf() && startOrAfter && beforeEnd) { stop = cb(node) if stop { return stop } } if node.IsLeaf() { return stop } if ascending { if afterStart { stop = node.getLeftNode().TraverseInRange(start, end, ascending, leavesOnly, cb) } if stop { return stop } if beforeEnd { stop = node.getRightNode().TraverseInRange(start, end, ascending, leavesOnly, cb) } } else { if beforeEnd { stop = node.getRightNode().TraverseInRange(start, end, ascending, leavesOnly, cb) } if stop { return stop } if afterStart { stop = node.getLeftNode().TraverseInRange(start, end, ascending, leavesOnly, cb) } } return stop } func (node *Node) TraverseByOffset(offset, limit int, ascending bool, leavesOnly bool, cb func(*Node) bool) bool { if node == nil { return false } if offset < 0 { offset = 0 } if limit <= 0 || offset >= node.size { return false } if node.IsLeaf() { if offset > 0 { return false } return cb(node) } return node.traverseByOffset(offset, limit, ascending, leavesOnly, cb) } func (node *Node) traverseByOffset(offset, limit int, ascending bool, leavesOnly bool, cb func(*Node) bool) bool { if !leavesOnly { if cb(node) { return true // Stop traversal if callback returns true } } first, second := node.getLeftNode(), node.getRightNode() if !ascending { first, second = second, first } if first.IsLeaf() { if offset > 0 { offset-- } else { if cb(first) { return true // Stop traversal if callback returns true } limit-- if limit <= 0 { return true // Stop traversal when limit is reached } } } else { if offset >= first.size { offset -= first.size // 1 } else { if first.traverseByOffset(offset, limit, ascending, leavesOnly, cb) { return true } delta := first.size - offset offset = 0 if delta >= limit { return true // 3 } limit -= delta // 2 } } if second.IsLeaf() { return cb(second) } return second.traverseByOffset(offset, limit, ascending, leavesOnly, cb) } func (node *Node) lmd() *Node { if node.height == 0 { return node } return node.getLeftNode().lmd() } func (node *Node) rmd() *Node { if node.height == 0 { return node } return node.getRightNode().rmd() } func maxInt8(a, b int8) int8 { if a > b { return a } return b }
- #6tree.gno
- #7package avl type ITree interface { Size() int Has(key string) bool Get(key string) any GetByIndex(index int) (key string, value any) Iterate(start, end string, cb IterCbFn) bool ReverseIterate(start, end string, cb IterCbFn) bool IterateByOffset(offset int, count int, cb IterCbFn) bool ReverseIterateByOffset(offset int, count int, cb IterCbFn) bool Set(key string, value any) (updated bool) Remove(key string) (value any, removed bool) } type IterCbFn func(key string, value any) bool type Tree struct { node *Node } func NewTree() *Tree { return &Tree{ node: nil, } } func (tree *Tree) Size() int { return tree.node.Size() } func (tree *Tree) Has(key string) (has bool) { return tree.node.Has(key) } func (tree *Tree) Get(key string) any { _, value, _ := tree.node.Get(key) return value } func (tree *Tree) GetByIndex(index int) (key string, value any) { return tree.node.GetByIndex(index) } func (tree *Tree) Set(key string, value any) (updated bool) { newnode, updated := tree.node.Set(key, value) tree.node = newnode return updated } func (tree *Tree) Remove(key string) (value any, removed bool) { newnode, _, value, removed := tree.node.Remove(key) tree.node = newnode return value, removed } func (tree *Tree) Iterate(start, end string, cb IterCbFn) bool { return tree.node.TraverseInRange(start, end, true, true, func(node *Node) bool { return cb(node.Key(), node.Value()) }, ) } func (tree *Tree) ReverseIterate(start, end string, cb IterCbFn) bool { return tree.node.TraverseInRange(start, end, false, true, func(node *Node) bool { return cb(node.Key(), node.Value()) }, ) } func (tree *Tree) IterateByOffset(offset int, count int, cb IterCbFn) bool { return tree.node.TraverseByOffset(offset, count, true, true, func(node *Node) bool { return cb(node.Key(), node.Value()) }, ) } func (tree *Tree) ReverseIterateByOffset(offset int, count int, cb IterCbFn) bool { return tree.node.TraverseByOffset(offset, count, false, true, func(node *Node) bool { return cb(node.Key(), node.Value()) }, ) } var _ ITree = (*Tree)(nil)
- #8/gno.MemPackageType
- #9 MPUserAll
Result log
msg:0,success:true,log:,events:[]