You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.4 KiB

10 years ago
10 years ago
10 years ago
  1. package merkle
  2. import (
  3. . "github.com/tendermint/tendermint/binary"
  4. )
  5. const HASH_BYTE_SIZE int = 4+32
  6. /*
  7. Immutable AVL Tree (wraps the Node root)
  8. This tree is not concurrency safe.
  9. You must wrap your calls with your own mutex.
  10. */
  11. type IAVLTree struct {
  12. db Db
  13. root *IAVLNode
  14. }
  15. func NewIAVLTree(db Db) *IAVLTree {
  16. return &IAVLTree{db:db, root:nil}
  17. }
  18. func NewIAVLTreeFromHash(db Db, hash ByteSlice) *IAVLTree {
  19. root := &IAVLNode{
  20. hash: hash,
  21. flags: IAVLNODE_FLAG_PERSISTED | IAVLNODE_FLAG_PLACEHOLDER,
  22. }
  23. root.fill(db)
  24. return &IAVLTree{db:db, root:root}
  25. }
  26. func (t *IAVLTree) Root() Node {
  27. return t.root
  28. }
  29. func (t *IAVLTree) Size() uint64 {
  30. if t.root == nil { return 0 }
  31. return t.root.Size()
  32. }
  33. func (t *IAVLTree) Height() uint8 {
  34. if t.root == nil { return 0 }
  35. return t.root.Height()
  36. }
  37. func (t *IAVLTree) Has(key Key) bool {
  38. if t.root == nil { return false }
  39. return t.root.has(t.db, key)
  40. }
  41. func (t *IAVLTree) Put(key Key, value Value) (updated bool) {
  42. if t.root == nil {
  43. t.root = NewIAVLNode(key, value)
  44. return false
  45. }
  46. t.root, updated = t.root.put(t.db, key, value)
  47. return updated
  48. }
  49. func (t *IAVLTree) Hash() (ByteSlice, uint64) {
  50. if t.root == nil { return nil, 0 }
  51. return t.root.Hash()
  52. }
  53. func (t *IAVLTree) Save() {
  54. if t.root == nil { return }
  55. if t.root.hash == nil {
  56. t.root.Hash()
  57. }
  58. t.root.Save(t.db)
  59. }
  60. func (t *IAVLTree) Get(key Key) (value Value) {
  61. if t.root == nil { return nil }
  62. return t.root.get(t.db, key)
  63. }
  64. func (t *IAVLTree) Remove(key Key) (value Value, err error) {
  65. if t.root == nil { return nil, NotFound(key) }
  66. newRoot, _, value, err := t.root.remove(t.db, key)
  67. if err != nil {
  68. return nil, err
  69. }
  70. t.root = newRoot
  71. return value, nil
  72. }
  73. func (t *IAVLTree) Copy() Tree {
  74. return &IAVLTree{db:t.db, root:t.root}
  75. }
  76. // Traverses all the nodes of the tree in prefix order.
  77. // return true from cb to halt iteration.
  78. // node.Height() == 0 if you just want a value node.
  79. func (t *IAVLTree) Traverse(cb func(Node) bool) {
  80. if t.root == nil { return }
  81. t.root.traverse(t.db, cb)
  82. }
  83. func (t *IAVLTree) Values() <-chan Value {
  84. root := t.root
  85. ch := make(chan Value)
  86. go func() {
  87. root.traverse(t.db, func(n Node) bool {
  88. if n.Height() == 0 { ch <- n.Value() }
  89. return true
  90. })
  91. close(ch)
  92. }()
  93. return ch
  94. }