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.

253 lines
5.4 KiB

10 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
10 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
10 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
10 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
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package merkle
  2. import (
  3. "bytes"
  4. "container/list"
  5. "sync"
  6. . "github.com/tendermint/tendermint/binary"
  7. db_ "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_.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. if len(hash) == 0 {
  111. panic("IAVLTree.Load() hash was nil")
  112. }
  113. t.root = t.ndb.GetNode(t, hash)
  114. }
  115. func (t *IAVLTree) Get(key interface{}) (index uint64, value interface{}) {
  116. if t.root == nil {
  117. return 0, nil
  118. }
  119. return t.root.get(t, key)
  120. }
  121. func (t *IAVLTree) GetByIndex(index uint64) (key interface{}, value interface{}) {
  122. if t.root == nil {
  123. return nil, nil
  124. }
  125. return t.root.getByIndex(t, index)
  126. }
  127. func (t *IAVLTree) Remove(key interface{}) (value interface{}, removed bool) {
  128. if t.root == nil {
  129. return nil, false
  130. }
  131. newRootHash, newRoot, _, value, removed := t.root.remove(t, key)
  132. if !removed {
  133. return nil, false
  134. }
  135. if newRoot == nil && newRootHash != nil {
  136. t.root = t.ndb.GetNode(t, newRootHash)
  137. } else {
  138. t.root = newRoot
  139. }
  140. return value, true
  141. }
  142. func (t *IAVLTree) Iterate(fn func(key interface{}, value interface{}) bool) (stopped bool) {
  143. if t.root == nil {
  144. return false
  145. }
  146. return t.root.traverse(t, func(node *IAVLNode) bool {
  147. if node.height == 0 {
  148. return fn(node.key, node.value)
  149. } else {
  150. return false
  151. }
  152. })
  153. }
  154. //-----------------------------------------------------------------------------
  155. type nodeElement struct {
  156. node *IAVLNode
  157. elem *list.Element
  158. }
  159. type nodeDB struct {
  160. mtx sync.Mutex
  161. cache map[string]nodeElement
  162. cacheSize int
  163. cacheQueue *list.List
  164. db db_.DB
  165. }
  166. func newNodeDB(cacheSize int, db db_.DB) *nodeDB {
  167. return &nodeDB{
  168. cache: make(map[string]nodeElement),
  169. cacheSize: cacheSize,
  170. cacheQueue: list.New(),
  171. db: db,
  172. }
  173. }
  174. func (ndb *nodeDB) GetNode(t *IAVLTree, hash []byte) *IAVLNode {
  175. ndb.mtx.Lock()
  176. defer ndb.mtx.Unlock()
  177. // Check the cache.
  178. nodeElem, ok := ndb.cache[string(hash)]
  179. if ok {
  180. // Already exists. Move to back of cacheQueue.
  181. ndb.cacheQueue.MoveToBack(nodeElem.elem)
  182. return nodeElem.node
  183. } else {
  184. // Doesn't exist, load.
  185. buf := ndb.db.Get(hash)
  186. r := bytes.NewReader(buf)
  187. var n int64
  188. var err error
  189. node := ReadIAVLNode(t, r, &n, &err)
  190. if err != nil {
  191. panic(err)
  192. }
  193. node.persisted = true
  194. ndb.cacheNode(node)
  195. return node
  196. }
  197. }
  198. func (ndb *nodeDB) SaveNode(t *IAVLTree, node *IAVLNode) {
  199. ndb.mtx.Lock()
  200. defer ndb.mtx.Unlock()
  201. if node.hash == nil {
  202. panic("Expected to find node.hash, but none found.")
  203. }
  204. if node.persisted {
  205. panic("Shouldn't be calling save on an already persisted node.")
  206. }
  207. if _, ok := ndb.cache[string(node.hash)]; ok {
  208. panic("Shouldn't be calling save on an already cached node.")
  209. }
  210. // Save node bytes to db
  211. buf := bytes.NewBuffer(nil)
  212. _, _, err := node.writeToCountHashes(t, buf)
  213. if err != nil {
  214. panic(err)
  215. }
  216. ndb.db.Set(node.hash, buf.Bytes())
  217. node.persisted = true
  218. ndb.cacheNode(node)
  219. }
  220. func (ndb *nodeDB) cacheNode(node *IAVLNode) {
  221. // Create entry in cache and append to cacheQueue.
  222. elem := ndb.cacheQueue.PushBack(node.hash)
  223. ndb.cache[string(node.hash)] = nodeElement{node, elem}
  224. // Maybe expire an item.
  225. if ndb.cacheQueue.Len() > ndb.cacheSize {
  226. hash := ndb.cacheQueue.Remove(ndb.cacheQueue.Front()).([]byte)
  227. delete(ndb.cache, string(hash))
  228. }
  229. }