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.

250 lines
5.3 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
  1. package merkle
  2. import (
  3. "bytes"
  4. "container/list"
  5. "sync"
  6. . "github.com/tendermint/tendermint/binary"
  7. . "github.com/tendermint/tendermint/db"
  8. )
  9. /*
  10. Immutable AVL Tree (wraps the Node root)
  11. This tree is not goroutine safe.
  12. */
  13. type IAVLTree struct {
  14. keyCodec Codec
  15. valueCodec Codec
  16. root *IAVLNode
  17. ndb *nodeDB
  18. }
  19. func NewIAVLTree(keyCodec, valueCodec Codec, cacheSize int, db DB) *IAVLTree {
  20. if db == nil {
  21. // In-memory IAVLTree
  22. return &IAVLTree{
  23. keyCodec: keyCodec,
  24. valueCodec: valueCodec,
  25. }
  26. } else {
  27. // Persistent IAVLTree
  28. return &IAVLTree{
  29. keyCodec: keyCodec,
  30. valueCodec: valueCodec,
  31. ndb: newNodeDB(cacheSize, db),
  32. }
  33. }
  34. }
  35. // The returned tree and the original tree are goroutine independent.
  36. // That is, they can each run in their own goroutine.
  37. func (t *IAVLTree) Copy() Tree {
  38. if t.root == nil {
  39. return &IAVLTree{
  40. keyCodec: t.keyCodec,
  41. valueCodec: t.valueCodec,
  42. root: nil,
  43. ndb: t.ndb,
  44. }
  45. }
  46. if t.ndb != nil && !t.root.persisted {
  47. // Saving a tree finalizes all the nodes.
  48. // It sets all the hashes recursively,
  49. // clears all the leftNode/rightNode values recursively,
  50. // and all the .persisted flags get set.
  51. panic("It is unsafe to Copy() an unpersisted tree.")
  52. } else if t.ndb == nil && t.root.hash == nil {
  53. // An in-memory IAVLTree is finalized when the hashes are
  54. // calculated.
  55. t.root.hashWithCount(t)
  56. }
  57. return &IAVLTree{
  58. keyCodec: t.keyCodec,
  59. valueCodec: t.valueCodec,
  60. root: t.root,
  61. ndb: t.ndb,
  62. }
  63. }
  64. func (t *IAVLTree) Size() uint64 {
  65. if t.root == nil {
  66. return 0
  67. }
  68. return t.root.size
  69. }
  70. func (t *IAVLTree) Height() uint8 {
  71. if t.root == nil {
  72. return 0
  73. }
  74. return t.root.height
  75. }
  76. func (t *IAVLTree) Has(key interface{}) bool {
  77. if t.root == nil {
  78. return false
  79. }
  80. return t.root.has(t, key)
  81. }
  82. func (t *IAVLTree) Set(key interface{}, value interface{}) (updated bool) {
  83. if t.root == nil {
  84. t.root = NewIAVLNode(key, value)
  85. return false
  86. }
  87. t.root, updated = t.root.set(t, key, value)
  88. return updated
  89. }
  90. func (t *IAVLTree) Hash() []byte {
  91. if t.root == nil {
  92. return nil
  93. }
  94. hash, _ := t.root.hashWithCount(t)
  95. return hash
  96. }
  97. func (t *IAVLTree) HashWithCount() ([]byte, uint64) {
  98. if t.root == nil {
  99. return nil, 0
  100. }
  101. return t.root.hashWithCount(t)
  102. }
  103. func (t *IAVLTree) Save() []byte {
  104. if t.root == nil {
  105. return nil
  106. }
  107. return t.root.save(t)
  108. }
  109. func (t *IAVLTree) Load(hash []byte) {
  110. t.root = t.ndb.GetNode(t, hash)
  111. }
  112. func (t *IAVLTree) Get(key interface{}) (index uint64, value interface{}) {
  113. if t.root == nil {
  114. return 0, nil
  115. }
  116. return t.root.get(t, key)
  117. }
  118. func (t *IAVLTree) GetByIndex(index uint64) (key interface{}, value interface{}) {
  119. if t.root == nil {
  120. return nil, nil
  121. }
  122. return t.root.getByIndex(t, index)
  123. }
  124. func (t *IAVLTree) Remove(key interface{}) (value interface{}, removed bool) {
  125. if t.root == nil {
  126. return nil, false
  127. }
  128. newRootHash, newRoot, _, value, removed := t.root.remove(t, key)
  129. if !removed {
  130. return nil, false
  131. }
  132. if newRoot == nil && newRootHash != nil {
  133. t.root = t.ndb.GetNode(t, newRootHash)
  134. } else {
  135. t.root = newRoot
  136. }
  137. return value, true
  138. }
  139. func (t *IAVLTree) Iterate(fn func(key interface{}, value interface{}) bool) (stopped bool) {
  140. if t.root == nil {
  141. return false
  142. }
  143. return t.root.traverse(t, func(node *IAVLNode) bool {
  144. if node.height == 0 {
  145. return fn(node.key, node.value)
  146. } else {
  147. return false
  148. }
  149. })
  150. }
  151. //-----------------------------------------------------------------------------
  152. type nodeElement struct {
  153. node *IAVLNode
  154. elem *list.Element
  155. }
  156. type nodeDB struct {
  157. mtx sync.Mutex
  158. cache map[string]nodeElement
  159. cacheSize int
  160. cacheQueue *list.List
  161. db DB
  162. }
  163. func newNodeDB(cacheSize int, db DB) *nodeDB {
  164. return &nodeDB{
  165. cache: make(map[string]nodeElement),
  166. cacheSize: cacheSize,
  167. cacheQueue: list.New(),
  168. db: db,
  169. }
  170. }
  171. func (ndb *nodeDB) GetNode(t *IAVLTree, hash []byte) *IAVLNode {
  172. ndb.mtx.Lock()
  173. defer ndb.mtx.Unlock()
  174. // Check the cache.
  175. nodeElem, ok := ndb.cache[string(hash)]
  176. if ok {
  177. // Already exists. Move to back of cacheQueue.
  178. ndb.cacheQueue.MoveToBack(nodeElem.elem)
  179. return nodeElem.node
  180. } else {
  181. // Doesn't exist, load.
  182. buf := ndb.db.Get(hash)
  183. r := bytes.NewReader(buf)
  184. var n int64
  185. var err error
  186. node := ReadIAVLNode(t, r, &n, &err)
  187. if err != nil {
  188. panic(err)
  189. }
  190. node.persisted = true
  191. ndb.cacheNode(node)
  192. return node
  193. }
  194. }
  195. func (ndb *nodeDB) SaveNode(t *IAVLTree, node *IAVLNode) {
  196. ndb.mtx.Lock()
  197. defer ndb.mtx.Unlock()
  198. if node.hash == nil {
  199. panic("Expected to find node.hash, but none found.")
  200. }
  201. if node.persisted {
  202. panic("Shouldn't be calling save on an already persisted node.")
  203. }
  204. if _, ok := ndb.cache[string(node.hash)]; ok {
  205. panic("Shouldn't be calling save on an already cached node.")
  206. }
  207. // Save node bytes to db
  208. buf := bytes.NewBuffer(nil)
  209. _, _, err := node.writeToCountHashes(t, buf)
  210. if err != nil {
  211. panic(err)
  212. }
  213. ndb.db.Set(node.hash, buf.Bytes())
  214. node.persisted = true
  215. ndb.cacheNode(node)
  216. }
  217. func (ndb *nodeDB) cacheNode(node *IAVLNode) {
  218. // Create entry in cache and append to cacheQueue.
  219. elem := ndb.cacheQueue.PushBack(node.hash)
  220. ndb.cache[string(node.hash)] = nodeElement{node, elem}
  221. // Maybe expire an item.
  222. if ndb.cacheQueue.Len() > ndb.cacheSize {
  223. hash := ndb.cacheQueue.Remove(ndb.cacheQueue.Front()).([]byte)
  224. delete(ndb.cache, string(hash))
  225. }
  226. }