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.

266 lines
5.4 KiB

10 years ago
  1. package common
  2. import ()
  3. // This immutable balanced binary tree happens to be an
  4. // immutable AVL+ tree, adapted from tendermint/merkle.
  5. // Unlike that one, this is in-memory, non-merkleized,
  6. // and nodes can be nil to signify an empty tree.
  7. type IBBSTree struct {
  8. key uint64
  9. value interface{}
  10. size uint64
  11. height uint8
  12. left *IBBSTree
  13. right *IBBSTree
  14. }
  15. // Creates an empty tree.
  16. func NewIBBSTree() *IBBSTree {
  17. return nil
  18. }
  19. // Creates a single tree node from key and value.
  20. func NewIBBSTreeNode(key uint64, value interface{}) *IBBSTree {
  21. return &IBBSTree{
  22. key: key,
  23. value: value,
  24. size: 1,
  25. }
  26. }
  27. func (self *IBBSTree) Copy() *IBBSTree {
  28. if self == nil {
  29. return nil
  30. }
  31. return &IBBSTree{
  32. key: self.key,
  33. value: self.value,
  34. size: self.size,
  35. height: self.height,
  36. left: self.left,
  37. right: self.right,
  38. }
  39. }
  40. func (self *IBBSTree) Size() uint64 {
  41. if self == nil {
  42. return 0
  43. }
  44. return self.size
  45. }
  46. func (self *IBBSTree) Height() uint8 {
  47. if self == nil {
  48. return 0
  49. }
  50. return self.height
  51. }
  52. func (self *IBBSTree) Has(key uint64) (has bool) {
  53. if self == nil {
  54. return false
  55. }
  56. if self.key == key {
  57. return true
  58. }
  59. if self.height == 0 {
  60. return false
  61. } else {
  62. if key < self.key {
  63. return self.left.Has(key)
  64. } else {
  65. return self.right.Has(key)
  66. }
  67. }
  68. }
  69. func (self *IBBSTree) Get(key uint64) (value interface{}) {
  70. if self == nil {
  71. return nil
  72. }
  73. if self.height == 0 {
  74. if self.key == key {
  75. return self.value
  76. } else {
  77. return nil
  78. }
  79. } else {
  80. if key < self.key {
  81. return self.left.Get(key)
  82. } else {
  83. return self.right.Get(key)
  84. }
  85. }
  86. }
  87. func (self *IBBSTree) Set(key uint64, value interface{}) (_ *IBBSTree, updated bool) {
  88. if self == nil {
  89. return NewIBBSTreeNode(key, value), false
  90. }
  91. if self.height == 0 {
  92. if key < self.key {
  93. return &IBBSTree{
  94. key: self.key,
  95. height: 1,
  96. size: 2,
  97. left: NewIBBSTreeNode(key, value),
  98. right: self,
  99. }, false
  100. } else if self.key == key {
  101. return NewIBBSTreeNode(key, value), true
  102. } else {
  103. return &IBBSTree{
  104. key: key,
  105. height: 1,
  106. size: 2,
  107. left: self,
  108. right: NewIBBSTreeNode(key, value),
  109. }, false
  110. }
  111. } else {
  112. self = self.Copy()
  113. if key < self.key {
  114. self.left, updated = self.left.Set(key, value)
  115. } else {
  116. self.right, updated = self.right.Set(key, value)
  117. }
  118. if updated {
  119. return self, updated
  120. } else {
  121. self.calcHeightAndSize()
  122. return self.balance(), updated
  123. }
  124. }
  125. }
  126. func (self *IBBSTree) Remove(key uint64) (newSelf *IBBSTree, value interface{}, removed bool) {
  127. newSelf, _, _, value, removed = self.remove(key)
  128. return
  129. }
  130. // newKey: new leftmost leaf key for tree after successfully removing 'key' if changed.
  131. func (self *IBBSTree) remove(key uint64) (newSelf *IBBSTree, hasNewKey bool, newKey uint64, value interface{}, removed bool) {
  132. if self == nil {
  133. return nil, false, 0, nil, false
  134. }
  135. if self.height == 0 {
  136. if self.key == key {
  137. return nil, false, 0, self.value, true
  138. } else {
  139. return self, false, 0, nil, false
  140. }
  141. } else {
  142. if key < self.key {
  143. var newLeft *IBBSTree
  144. newLeft, hasNewKey, newKey, value, removed = self.left.remove(key)
  145. if !removed {
  146. return self, false, 0, value, false
  147. } else if newLeft == nil { // left node held value, was removed
  148. return self.right, true, self.key, value, true
  149. }
  150. self = self.Copy()
  151. self.left = newLeft
  152. } else {
  153. var newRight *IBBSTree
  154. newRight, hasNewKey, newKey, value, removed = self.right.remove(key)
  155. if !removed {
  156. return self, false, 0, value, false
  157. } else if newRight == nil { // right node held value, was removed
  158. return self.left, false, 0, value, true
  159. }
  160. self = self.Copy()
  161. self.right = newRight
  162. if hasNewKey {
  163. self.key = newKey
  164. hasNewKey = false
  165. newKey = 0
  166. }
  167. }
  168. self.calcHeightAndSize()
  169. return self.balance(), hasNewKey, newKey, value, true
  170. }
  171. }
  172. func (self *IBBSTree) rotateRight() *IBBSTree {
  173. self = self.Copy()
  174. sl := self.left.Copy()
  175. slr := sl.right
  176. sl.right = self
  177. self.left = slr
  178. self.calcHeightAndSize()
  179. sl.calcHeightAndSize()
  180. return sl
  181. }
  182. func (self *IBBSTree) rotateLeft() *IBBSTree {
  183. self = self.Copy()
  184. sr := self.right.Copy()
  185. srl := sr.left
  186. sr.left = self
  187. self.right = srl
  188. self.calcHeightAndSize()
  189. sr.calcHeightAndSize()
  190. return sr
  191. }
  192. func (self *IBBSTree) calcHeightAndSize() {
  193. self.height = MaxUint8(self.left.Height(), self.right.Height()) + 1
  194. self.size = self.left.Size() + self.right.Size()
  195. }
  196. func (self *IBBSTree) calcBalance() int {
  197. return int(self.left.Height()) - int(self.right.Height())
  198. }
  199. func (self *IBBSTree) balance() (newSelf *IBBSTree) {
  200. balance := self.calcBalance()
  201. if balance > 1 {
  202. if self.left.calcBalance() >= 0 {
  203. // Left Left Case
  204. return self.rotateRight()
  205. } else {
  206. // Left Right Case
  207. self = self.Copy()
  208. self.left = self.left.rotateLeft()
  209. //self.calcHeightAndSize()
  210. return self.rotateRight()
  211. }
  212. }
  213. if balance < -1 {
  214. if self.right.calcBalance() <= 0 {
  215. // Right Right Case
  216. return self.rotateLeft()
  217. } else {
  218. // Right Left Case
  219. self = self.Copy()
  220. self.right = self.right.rotateRight()
  221. //self.calcHeightAndSize()
  222. return self.rotateLeft()
  223. }
  224. }
  225. // Nothing changed
  226. return self
  227. }
  228. // Iteration stops when stop is returned.
  229. func (self *IBBSTree) Iterate(cb func(uint64, interface{}) bool) bool {
  230. if self == nil {
  231. return false
  232. }
  233. if self.height == 0 {
  234. return cb(self.key, self.value)
  235. } else {
  236. stop := self.left.Iterate(cb)
  237. if stop {
  238. return stop
  239. }
  240. return self.right.Iterate(cb)
  241. }
  242. }