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.

408 lines
9.8 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
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
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. "crypto/sha256"
  4. "io"
  5. "github.com/tendermint/tendermint/binary"
  6. )
  7. // Node
  8. type IAVLNode struct {
  9. key interface{}
  10. value interface{}
  11. size uint64
  12. height uint8
  13. hash []byte
  14. leftHash []byte
  15. leftNode *IAVLNode
  16. rightHash []byte
  17. rightNode *IAVLNode
  18. persisted bool
  19. }
  20. func NewIAVLNode(key interface{}, value interface{}) *IAVLNode {
  21. return &IAVLNode{
  22. key: key,
  23. value: value,
  24. size: 1,
  25. }
  26. }
  27. func ReadIAVLNode(t *IAVLTree, r io.Reader, n *int64, err *error) *IAVLNode {
  28. node := &IAVLNode{}
  29. // node header & key
  30. node.height = binary.ReadUint8(r, n, err)
  31. node.size = binary.ReadUint64(r, n, err)
  32. node.key = t.keyCodec.Decode(r, n, err)
  33. if *err != nil {
  34. panic(*err)
  35. }
  36. // node value or children.
  37. if node.height == 0 {
  38. node.value = t.valueCodec.Decode(r, n, err)
  39. } else {
  40. node.leftHash = binary.ReadByteSlice(r, n, err)
  41. node.rightHash = binary.ReadByteSlice(r, n, err)
  42. }
  43. if *err != nil {
  44. panic(*err)
  45. }
  46. return node
  47. }
  48. func (node *IAVLNode) _copy() *IAVLNode {
  49. if node.height == 0 {
  50. panic("Why are you copying a value node?")
  51. }
  52. return &IAVLNode{
  53. key: node.key,
  54. size: node.size,
  55. height: node.height,
  56. hash: nil, // Going to be mutated anyways.
  57. leftHash: node.leftHash,
  58. leftNode: node.leftNode,
  59. rightHash: node.rightHash,
  60. rightNode: node.rightNode,
  61. persisted: false, // Going to be mutated, so it can't already be persisted.
  62. }
  63. }
  64. func (node *IAVLNode) has(t *IAVLTree, key interface{}) (has bool) {
  65. if t.keyCodec.Compare(node.key, key) == 0 {
  66. return true
  67. }
  68. if node.height == 0 {
  69. return false
  70. } else {
  71. if t.keyCodec.Compare(key, node.key) < 0 {
  72. return node.getLeftNode(t).has(t, key)
  73. } else {
  74. return node.getRightNode(t).has(t, key)
  75. }
  76. }
  77. }
  78. func (node *IAVLNode) get(t *IAVLTree, key interface{}) (index uint64, value interface{}) {
  79. if node.height == 0 {
  80. if t.keyCodec.Compare(node.key, key) == 0 {
  81. return 0, node.value
  82. } else {
  83. return 0, nil
  84. }
  85. } else {
  86. if t.keyCodec.Compare(key, node.key) < 0 {
  87. return node.getLeftNode(t).get(t, key)
  88. } else {
  89. rightNode := node.getRightNode(t)
  90. index, value = rightNode.get(t, key)
  91. index += node.size - rightNode.size
  92. return index, value
  93. }
  94. }
  95. }
  96. func (node *IAVLNode) getByIndex(t *IAVLTree, index uint64) (key interface{}, value interface{}) {
  97. if node.height == 0 {
  98. if index == 0 {
  99. return node.key, node.value
  100. } else {
  101. panic("getByIndex asked for invalid index")
  102. }
  103. } else {
  104. // TODO: could improve this by storing the
  105. // sizes as well as left/right hash.
  106. leftNode := node.getLeftNode(t)
  107. if index < leftNode.size {
  108. return leftNode.getByIndex(t, index)
  109. } else {
  110. return node.getRightNode(t).getByIndex(t, index-leftNode.size)
  111. }
  112. }
  113. }
  114. // NOTE: sets hashes recursively
  115. func (node *IAVLNode) hashWithCount(t *IAVLTree) ([]byte, uint64) {
  116. if node.hash != nil {
  117. return node.hash, 0
  118. }
  119. hasher := sha256.New()
  120. _, hashCount, err := node.writeToCountHashes(t, hasher)
  121. if err != nil {
  122. panic(err)
  123. }
  124. node.hash = hasher.Sum(nil)
  125. return node.hash, hashCount + 1
  126. }
  127. // NOTE: sets hashes recursively
  128. // NOTE: clears leftNode/rightNode recursively
  129. func (node *IAVLNode) save(t *IAVLTree) []byte {
  130. if node.hash == nil {
  131. node.hash, _ = node.hashWithCount(t)
  132. }
  133. if node.persisted {
  134. return node.hash
  135. }
  136. // save children
  137. if node.leftNode != nil {
  138. node.leftHash = node.leftNode.save(t)
  139. node.leftNode = nil
  140. }
  141. if node.rightNode != nil {
  142. node.rightHash = node.rightNode.save(t)
  143. node.rightNode = nil
  144. }
  145. // save node
  146. t.ndb.SaveNode(t, node)
  147. return node.hash
  148. }
  149. func (node *IAVLNode) set(t *IAVLTree, key interface{}, value interface{}) (newSelf *IAVLNode, updated bool) {
  150. if node.height == 0 {
  151. cmp := t.keyCodec.Compare(key, node.key)
  152. if cmp < 0 {
  153. return &IAVLNode{
  154. key: node.key,
  155. height: 1,
  156. size: 2,
  157. leftNode: NewIAVLNode(key, value),
  158. rightNode: node,
  159. }, false
  160. } else if cmp == 0 {
  161. return NewIAVLNode(key, value), true
  162. } else {
  163. return &IAVLNode{
  164. key: key,
  165. height: 1,
  166. size: 2,
  167. leftNode: node,
  168. rightNode: NewIAVLNode(key, value),
  169. }, false
  170. }
  171. } else {
  172. node = node._copy()
  173. if t.keyCodec.Compare(key, node.key) < 0 {
  174. node.leftNode, updated = node.getLeftNode(t).set(t, key, value)
  175. node.leftHash = nil
  176. } else {
  177. node.rightNode, updated = node.getRightNode(t).set(t, key, value)
  178. node.rightHash = nil
  179. }
  180. if updated {
  181. return node, updated
  182. } else {
  183. node.calcHeightAndSize(t)
  184. return node.balance(t), updated
  185. }
  186. }
  187. }
  188. // newHash/newNode: The new hash or node to replace node after remove.
  189. // newKey: new leftmost leaf key for tree after successfully removing 'key' if changed.
  190. // value: removed value.
  191. func (node *IAVLNode) remove(t *IAVLTree, key interface{}) (
  192. newHash []byte, newNode *IAVLNode, newKey interface{}, value interface{}, removed bool) {
  193. if node.height == 0 {
  194. if t.keyCodec.Compare(key, node.key) == 0 {
  195. return nil, nil, nil, node.value, true
  196. } else {
  197. return nil, node, nil, nil, false
  198. }
  199. } else {
  200. if t.keyCodec.Compare(key, node.key) < 0 {
  201. var newLeftHash []byte
  202. var newLeftNode *IAVLNode
  203. newLeftHash, newLeftNode, newKey, value, removed = node.getLeftNode(t).remove(t, key)
  204. if !removed {
  205. return nil, node, nil, value, false
  206. } else if newLeftHash == nil && newLeftNode == nil { // left node held value, was removed
  207. return node.rightHash, node.rightNode, node.key, value, true
  208. }
  209. node = node._copy()
  210. node.leftHash, node.leftNode = newLeftHash, newLeftNode
  211. node.calcHeightAndSize(t)
  212. return nil, node.balance(t), newKey, value, true
  213. } else {
  214. var newRightHash []byte
  215. var newRightNode *IAVLNode
  216. newRightHash, newRightNode, newKey, value, removed = node.getRightNode(t).remove(t, key)
  217. if !removed {
  218. return nil, node, nil, value, false
  219. } else if newRightHash == nil && newRightNode == nil { // right node held value, was removed
  220. return node.leftHash, node.leftNode, nil, value, true
  221. }
  222. node = node._copy()
  223. node.rightHash, node.rightNode = newRightHash, newRightNode
  224. if newKey != nil {
  225. node.key = newKey
  226. newKey = nil
  227. }
  228. node.calcHeightAndSize(t)
  229. return nil, node.balance(t), newKey, value, true
  230. }
  231. }
  232. }
  233. // NOTE: sets hashes recursively
  234. func (node *IAVLNode) writeToCountHashes(t *IAVLTree, w io.Writer) (n int64, hashCount uint64, err error) {
  235. // height & size & key
  236. binary.WriteUint8(node.height, w, &n, &err)
  237. binary.WriteUint64(node.size, w, &n, &err)
  238. t.keyCodec.Encode(node.key, w, &n, &err)
  239. if err != nil {
  240. return
  241. }
  242. if node.height == 0 {
  243. // value
  244. t.valueCodec.Encode(node.value, w, &n, &err)
  245. } else {
  246. // left
  247. if node.leftNode != nil {
  248. leftHash, leftCount := node.leftNode.hashWithCount(t)
  249. node.leftHash = leftHash
  250. hashCount += leftCount
  251. }
  252. if node.leftHash == nil {
  253. panic("node.leftHash was nil in save")
  254. }
  255. binary.WriteByteSlice(node.leftHash, w, &n, &err)
  256. // right
  257. if node.rightNode != nil {
  258. rightHash, rightCount := node.rightNode.hashWithCount(t)
  259. node.rightHash = rightHash
  260. hashCount += rightCount
  261. }
  262. if node.rightHash == nil {
  263. panic("node.rightHash was nil in save")
  264. }
  265. binary.WriteByteSlice(node.rightHash, w, &n, &err)
  266. }
  267. return
  268. }
  269. func (node *IAVLNode) getLeftNode(t *IAVLTree) *IAVLNode {
  270. if node.leftNode != nil {
  271. return node.leftNode
  272. } else {
  273. return t.ndb.GetNode(t, node.leftHash)
  274. }
  275. }
  276. func (node *IAVLNode) getRightNode(t *IAVLTree) *IAVLNode {
  277. if node.rightNode != nil {
  278. return node.rightNode
  279. } else {
  280. return t.ndb.GetNode(t, node.rightHash)
  281. }
  282. }
  283. func (node *IAVLNode) rotateRight(t *IAVLTree) *IAVLNode {
  284. node = node._copy()
  285. sl := node.getLeftNode(t)._copy()
  286. slrHash, slrCached := sl.rightHash, sl.rightNode
  287. sl.rightHash, sl.rightNode = nil, node
  288. node.leftHash, node.leftNode = slrHash, slrCached
  289. node.calcHeightAndSize(t)
  290. sl.calcHeightAndSize(t)
  291. return sl
  292. }
  293. func (node *IAVLNode) rotateLeft(t *IAVLTree) *IAVLNode {
  294. node = node._copy()
  295. sr := node.getRightNode(t)._copy()
  296. srlHash, srlCached := sr.leftHash, sr.leftNode
  297. sr.leftHash, sr.leftNode = nil, node
  298. node.rightHash, node.rightNode = srlHash, srlCached
  299. node.calcHeightAndSize(t)
  300. sr.calcHeightAndSize(t)
  301. return sr
  302. }
  303. // NOTE: mutates height and size
  304. func (node *IAVLNode) calcHeightAndSize(t *IAVLTree) {
  305. node.height = maxUint8(node.getLeftNode(t).height, node.getRightNode(t).height) + 1
  306. node.size = node.getLeftNode(t).size + node.getRightNode(t).size
  307. }
  308. func (node *IAVLNode) calcBalance(t *IAVLTree) int {
  309. return int(node.getLeftNode(t).height) - int(node.getRightNode(t).height)
  310. }
  311. func (node *IAVLNode) balance(t *IAVLTree) (newSelf *IAVLNode) {
  312. balance := node.calcBalance(t)
  313. if balance > 1 {
  314. if node.getLeftNode(t).calcBalance(t) >= 0 {
  315. // Left Left Case
  316. return node.rotateRight(t)
  317. } else {
  318. // Left Right Case
  319. node = node._copy()
  320. node.leftHash, node.leftNode = nil, node.getLeftNode(t).rotateLeft(t)
  321. //node.calcHeightAndSize()
  322. return node.rotateRight(t)
  323. }
  324. }
  325. if balance < -1 {
  326. if node.getRightNode(t).calcBalance(t) <= 0 {
  327. // Right Right Case
  328. return node.rotateLeft(t)
  329. } else {
  330. // Right Left Case
  331. node = node._copy()
  332. node.rightHash, node.rightNode = nil, node.getRightNode(t).rotateRight(t)
  333. //node.calcHeightAndSize()
  334. return node.rotateLeft(t)
  335. }
  336. }
  337. // Nothing changed
  338. return node
  339. }
  340. func (node *IAVLNode) traverse(t *IAVLTree, cb func(*IAVLNode) bool) bool {
  341. stop := cb(node)
  342. if stop {
  343. return stop
  344. }
  345. if node.height > 0 {
  346. stop = node.getLeftNode(t).traverse(t, cb)
  347. if stop {
  348. return stop
  349. }
  350. stop = node.getRightNode(t).traverse(t, cb)
  351. if stop {
  352. return stop
  353. }
  354. }
  355. return false
  356. }
  357. // Only used in testing...
  358. func (node *IAVLNode) lmd(t *IAVLTree) *IAVLNode {
  359. if node.height == 0 {
  360. return node
  361. }
  362. return node.getLeftNode(t).lmd(t)
  363. }
  364. // Only used in testing...
  365. func (node *IAVLNode) rmd(t *IAVLTree) *IAVLNode {
  366. if node.height == 0 {
  367. return node
  368. }
  369. return node.getRightNode(t).rmd(t)
  370. }