cursor.go 12 KB

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