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.

108 lines
2.4 KiB

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