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.

258 lines
5.6 KiB

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