cursor.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. package bolt
  2. import (
  3. "bytes"
  4. "fmt"
  5. "sort"
  6. )
  7. // Cursor represents an iterator that can traverse over all key/value pairs in a bucket in sorted order.
  8. // Cursors see nested buckets with value == nil.
  9. // Cursors can be obtained from a transaction and are valid as long as the transaction is open.
  10. //
  11. // Keys and values returned from the cursor are only valid for the life of the transaction.
  12. //
  13. // Changing data while traversing with a cursor may cause it to be invalidated
  14. // and return unexpected keys and/or values. You must reposition your cursor
  15. // after mutating data.
  16. type Cursor struct {
  17. bucket *Bucket
  18. stack []elemRef
  19. }
  20. // Bucket returns the bucket that this cursor was created from.
  21. func (c *Cursor) Bucket() *Bucket {
  22. return c.bucket
  23. }
  24. // First moves the cursor to the first item in the bucket and returns its key and value.
  25. // If the bucket is empty then a nil key and value are returned.
  26. // The returned key and value are only valid for the life of the transaction.
  27. func (c *Cursor) First() (key []byte, value []byte) {
  28. _assert(c.bucket.tx.db != nil, "tx closed")
  29. c.stack = c.stack[:0]
  30. p, n := c.bucket.pageNode(c.bucket.root)
  31. c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
  32. c.first()
  33. // If we land on an empty page then move to the next value.
  34. // https://github.com/boltdb/bolt/issues/450
  35. if c.stack[len(c.stack)-1].count() == 0 {
  36. c.next()
  37. }
  38. k, v, flags := c.keyValue()
  39. if (flags & uint32(bucketLeafFlag)) != 0 {
  40. return k, nil
  41. }
  42. return k, v
  43. }
  44. // Last moves the cursor to the last item in the bucket and returns its key and value.
  45. // If the bucket is empty then a nil key and value are returned.
  46. // The returned key and value are only valid for the life of the transaction.
  47. func (c *Cursor) Last() (key []byte, value []byte) {
  48. _assert(c.bucket.tx.db != nil, "tx closed")
  49. c.stack = c.stack[:0]
  50. p, n := c.bucket.pageNode(c.bucket.root)
  51. ref := elemRef{page: p, node: n}
  52. ref.index = ref.count() - 1
  53. c.stack = append(c.stack, ref)
  54. c.last()
  55. k, v, flags := c.keyValue()
  56. if (flags & uint32(bucketLeafFlag)) != 0 {
  57. return k, nil
  58. }
  59. return k, v
  60. }
  61. // Next moves the cursor to the next item in the bucket and returns its key and value.
  62. // If the cursor is at the end of the bucket then a nil key and value are returned.
  63. // The returned key and value are only valid for the life of the transaction.
  64. func (c *Cursor) Next() (key []byte, value []byte) {
  65. _assert(c.bucket.tx.db != nil, "tx closed")
  66. k, v, flags := c.next()
  67. if (flags & uint32(bucketLeafFlag)) != 0 {
  68. return k, nil
  69. }
  70. return k, v
  71. }
  72. // Prev moves the cursor to the previous item in the bucket and returns its key and value.
  73. // If the cursor is at the beginning of the bucket then a nil key and value are returned.
  74. // The returned key and value are only valid for the life of the transaction.
  75. func (c *Cursor) Prev() (key []byte, value []byte) {
  76. _assert(c.bucket.tx.db != nil, "tx closed")
  77. // Attempt to move back one element until we're successful.
  78. // Move up the stack as we hit the beginning of each page in our stack.
  79. for i := len(c.stack) - 1; i >= 0; i-- {
  80. elem := &c.stack[i]
  81. if elem.index > 0 {
  82. elem.index--
  83. break
  84. }
  85. c.stack = c.stack[:i]
  86. }
  87. // If we've hit the end then return nil.
  88. if len(c.stack) == 0 {
  89. return nil, nil
  90. }
  91. // Move down the stack to find the last element of the last leaf under this branch.
  92. c.last()
  93. k, v, flags := c.keyValue()
  94. if (flags & uint32(bucketLeafFlag)) != 0 {
  95. return k, nil
  96. }
  97. return k, v
  98. }
  99. // Seek moves the cursor to a given key and returns it.
  100. // If the key does not exist then the next key is used. If no keys
  101. // follow, a nil key is returned.
  102. // The returned key and value are only valid for the life of the transaction.
  103. func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
  104. k, v, flags := c.seek(seek)
  105. // If we ended up after the last element of a page then move to the next one.
  106. if ref := &c.stack[len(c.stack)-1]; ref.index >= ref.count() {
  107. k, v, flags = c.next()
  108. }
  109. if k == nil {
  110. return nil, nil
  111. } else if (flags & uint32(bucketLeafFlag)) != 0 {
  112. return k, nil
  113. }
  114. return k, v
  115. }
  116. // Delete removes the current key/value under the cursor from the bucket.
  117. // Delete fails if current key/value is a bucket or if the transaction is not writable.
  118. func (c *Cursor) Delete() error {
  119. if c.bucket.tx.db == nil {
  120. return ErrTxClosed
  121. } else if !c.bucket.Writable() {
  122. return ErrTxNotWritable
  123. }
  124. key, _, flags := c.keyValue()
  125. // Return an error if current value is a bucket.
  126. if (flags & bucketLeafFlag) != 0 {
  127. return ErrIncompatibleValue
  128. }
  129. c.node().del(key)
  130. return nil
  131. }
  132. // seek moves the cursor to a given key and returns it.
  133. // If the key does not exist then the next key is used.
  134. func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
  135. _assert(c.bucket.tx.db != nil, "tx closed")
  136. // Start from root page/node and traverse to correct page.
  137. c.stack = c.stack[:0]
  138. c.search(seek, c.bucket.root)
  139. ref := &c.stack[len(c.stack)-1]
  140. // If the cursor is pointing to the end of page/node then return nil.
  141. if ref.index >= ref.count() {
  142. return nil, nil, 0
  143. }
  144. // If this is a bucket then return a nil value.
  145. return c.keyValue()
  146. }
  147. // first moves the cursor to the first leaf element under the last page in the stack.
  148. func (c *Cursor) first() {
  149. for {
  150. // Exit when we hit a leaf page.
  151. var ref = &c.stack[len(c.stack)-1]
  152. if ref.isLeaf() {
  153. break
  154. }
  155. // Keep adding pages pointing to the first element to the stack.
  156. var pgid pgid
  157. if ref.node != nil {
  158. pgid = ref.node.inodes[ref.index].pgid
  159. } else {
  160. pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
  161. }
  162. p, n := c.bucket.pageNode(pgid)
  163. c.stack = append(c.stack, elemRef{page: p, node: n, index: 0})
  164. }
  165. }
  166. // last moves the cursor to the last leaf element under the last page in the stack.
  167. func (c *Cursor) last() {
  168. for {
  169. // Exit when we hit a leaf page.
  170. ref := &c.stack[len(c.stack)-1]
  171. if ref.isLeaf() {
  172. break
  173. }
  174. // Keep adding pages pointing to the last element in the stack.
  175. var pgid pgid
  176. if ref.node != nil {
  177. pgid = ref.node.inodes[ref.index].pgid
  178. } else {
  179. pgid = ref.page.branchPageElement(uint16(ref.index)).pgid
  180. }
  181. p, n := c.bucket.pageNode(pgid)
  182. var nextRef = elemRef{page: p, node: n}
  183. nextRef.index = nextRef.count() - 1
  184. c.stack = append(c.stack, nextRef)
  185. }
  186. }
  187. // next moves to the next leaf element and returns the key and value.
  188. // If the cursor is at the last leaf element then it stays there and returns nil.
  189. func (c *Cursor) next() (key []byte, value []byte, flags uint32) {
  190. for {
  191. // Attempt to move over one element until we're successful.
  192. // Move up the stack as we hit the end of each page in our stack.
  193. var i int
  194. for i = len(c.stack) - 1; i >= 0; i-- {
  195. elem := &c.stack[i]
  196. if elem.index < elem.count()-1 {
  197. elem.index++
  198. break
  199. }
  200. }
  201. // If we've hit the root page then stop and return. This will leave the
  202. // cursor on the last element of the last page.
  203. if i == -1 {
  204. return nil, nil, 0
  205. }
  206. // Otherwise start from where we left off in the stack and find the
  207. // first element of the first leaf page.
  208. c.stack = c.stack[:i+1]
  209. c.first()
  210. // If this is an empty page then restart and move back up the stack.
  211. // https://github.com/boltdb/bolt/issues/450
  212. if c.stack[len(c.stack)-1].count() == 0 {
  213. continue
  214. }
  215. return c.keyValue()
  216. }
  217. }
  218. // search recursively performs a binary search against a given page/node until it finds a given key.
  219. func (c *Cursor) search(key []byte, pgid pgid) {
  220. p, n := c.bucket.pageNode(pgid)
  221. if p != nil && (p.flags&(branchPageFlag|leafPageFlag)) == 0 {
  222. panic(fmt.Sprintf("invalid page type: %d: %x", p.id, p.flags))
  223. }
  224. e := elemRef{page: p, node: n}
  225. c.stack = append(c.stack, e)
  226. // If we're on a leaf page/node then find the specific node.
  227. if e.isLeaf() {
  228. c.nsearch(key)
  229. return
  230. }
  231. if n != nil {
  232. c.searchNode(key, n)
  233. return
  234. }
  235. c.searchPage(key, p)
  236. }
  237. func (c *Cursor) searchNode(key []byte, n *node) {
  238. var exact bool
  239. index := sort.Search(len(n.inodes), func(i int) bool {
  240. // TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
  241. // sort.Search() finds the lowest index where f() != -1 but we need the highest index.
  242. ret := bytes.Compare(n.inodes[i].key, key)
  243. if ret == 0 {
  244. exact = true
  245. }
  246. return ret != -1
  247. })
  248. if !exact && index > 0 {
  249. index--
  250. }
  251. c.stack[len(c.stack)-1].index = index
  252. // Recursively search to the next page.
  253. c.search(key, n.inodes[index].pgid)
  254. }
  255. func (c *Cursor) searchPage(key []byte, p *page) {
  256. // Binary search for the correct range.
  257. inodes := p.branchPageElements()
  258. var exact bool
  259. index := sort.Search(int(p.count), func(i int) bool {
  260. // TODO(benbjohnson): Optimize this range search. It's a bit hacky right now.
  261. // sort.Search() finds the lowest index where f() != -1 but we need the highest index.
  262. ret := bytes.Compare(inodes[i].key(), key)
  263. if ret == 0 {
  264. exact = true
  265. }
  266. return ret != -1
  267. })
  268. if !exact && index > 0 {
  269. index--
  270. }
  271. c.stack[len(c.stack)-1].index = index
  272. // Recursively search to the next page.
  273. c.search(key, inodes[index].pgid)
  274. }
  275. // nsearch searches the leaf node on the top of the stack for a key.
  276. func (c *Cursor) nsearch(key []byte) {
  277. e := &c.stack[len(c.stack)-1]
  278. p, n := e.page, e.node
  279. // If we have a node then search its inodes.
  280. if n != nil {
  281. index := sort.Search(len(n.inodes), func(i int) bool {
  282. return bytes.Compare(n.inodes[i].key, key) != -1
  283. })
  284. e.index = index
  285. return
  286. }
  287. // If we have a page then search its leaf elements.
  288. inodes := p.leafPageElements()
  289. index := sort.Search(int(p.count), func(i int) bool {
  290. return bytes.Compare(inodes[i].key(), key) != -1
  291. })
  292. e.index = index
  293. }
  294. // keyValue returns the key and value of the current leaf element.
  295. func (c *Cursor) keyValue() ([]byte, []byte, uint32) {
  296. ref := &c.stack[len(c.stack)-1]
  297. if ref.count() == 0 || ref.index >= ref.count() {
  298. return nil, nil, 0
  299. }
  300. // Retrieve value from node.
  301. if ref.node != nil {
  302. inode := &ref.node.inodes[ref.index]
  303. return inode.key, inode.value, inode.flags
  304. }
  305. // Or retrieve value from page.
  306. elem := ref.page.leafPageElement(uint16(ref.index))
  307. return elem.key(), elem.value(), elem.flags
  308. }
  309. // node returns the node that the cursor is currently positioned on.
  310. func (c *Cursor) node() *node {
  311. _assert(len(c.stack) > 0, "accessing a node with a zero-length cursor stack")
  312. // If the top of the stack is a leaf node then just return it.
  313. if ref := &c.stack[len(c.stack)-1]; ref.node != nil && ref.isLeaf() {
  314. return ref.node
  315. }
  316. // Start from root and traverse down the hierarchy.
  317. var n = c.stack[0].node
  318. if n == nil {
  319. n = c.bucket.node(c.stack[0].page.id, nil)
  320. }
  321. for _, ref := range c.stack[:len(c.stack)-1] {
  322. _assert(!n.isLeaf, "expected branch node")
  323. n = n.childAt(int(ref.index))
  324. }
  325. _assert(n.isLeaf, "expected leaf node")
  326. return n
  327. }
  328. // elemRef represents a reference to an element on a given page/node.
  329. type elemRef struct {
  330. page *page
  331. node *node
  332. index int
  333. }
  334. // isLeaf returns whether the ref is pointing at a leaf page/node.
  335. func (r *elemRef) isLeaf() bool {
  336. if r.node != nil {
  337. return r.node.isLeaf
  338. }
  339. return (r.page.flags & leafPageFlag) != 0
  340. }
  341. // count returns the number of inodes or page elements.
  342. func (r *elemRef) count() int {
  343. if r.node != nil {
  344. return len(r.node.inodes)
  345. }
  346. return int(r.page.count)
  347. }