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.

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