aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTommi Virtanen <tv@eagain.net>2014-02-20 10:55:04 -0800
committerTommi Virtanen <tv@eagain.net>2014-02-20 11:33:28 -0800
commit8438c6ebc3a6ccd05e33f7bc1e9648645f3c0831 (patch)
tree0b0c2119fbcf0296631f996c68e2e86b86df60e5
parentMerge pull request #43 from benbjohnson/cursor-godoc-fix (diff)
downloaddedo-8438c6ebc3a6ccd05e33f7bc1e9648645f3c0831.tar.gz
dedo-8438c6ebc3a6ccd05e33f7bc1e9648645f3c0831.tar.xz
Cursor.Get is now Cursor.Seek, and returns the first possible key.
This makes range and prefix queries possible. Closes: #44
-rw-r--r--cursor.go20
-rw-r--r--rwtransaction.go6
-rw-r--r--transaction.go11
3 files changed, 21 insertions, 16 deletions
diff --git a/cursor.go b/cursor.go
index 3262f4c..410bb89 100644
--- a/cursor.go
+++ b/cursor.go
@@ -48,32 +48,28 @@ func (c *Cursor) Next() (key []byte, value []byte) {
return c.keyValue()
}
-// Get moves the cursor to a given key and returns its value.
-// If the key does not exist then the cursor is left at the closest key and a nil value is returned.
-func (c *Cursor) Get(key []byte) (value []byte) {
+// Seek moves the cursor to a given key and returns it.
+// If the key does not exist then the next key is used. If no keys
+// follow, a nil value is returned.
+func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
// Start from root page and traverse to correct page.
c.stack = c.stack[:0]
- c.search(key, c.transaction.page(c.root))
+ c.search(seek, c.transaction.page(c.root))
p, index := c.top()
// If the cursor is pointing to the end of page then return nil.
if index == p.count {
- return nil
- }
-
- // If our target node isn't the same key as what's passed in then return nil.
- if !bytes.Equal(key, c.element().key()) {
- return nil
+ return nil, nil
}
- return c.element().value()
+ return c.element().key(), c.element().value()
}
// first moves the cursor to the first leaf element under the last page in the stack.
func (c *Cursor) first() {
p := c.stack[len(c.stack)-1].page
for {
- // Exit when we hit a leaf page.
+ // Exit when we hit a leaf page.
if (p.flags & leafPageFlag) != 0 {
break
}
diff --git a/rwtransaction.go b/rwtransaction.go
index 84e6425..e22c766 100644
--- a/rwtransaction.go
+++ b/rwtransaction.go
@@ -20,7 +20,7 @@ func (t *RWTransaction) init(db *DB) {
t.Transaction.init(db)
t.pages = make(map[pgid]*page)
- // Increment the transaction id.
+ // Increment the transaction id.
t.meta.txnid += txnid(1)
}
@@ -114,7 +114,7 @@ func (t *RWTransaction) Put(name string, key []byte, value []byte) error {
// Move cursor to correct position.
c := b.cursor()
- c.Get(key)
+ c.Seek(key)
// Insert the key/value.
c.node(t).put(key, key, value, 0)
@@ -133,7 +133,7 @@ func (t *RWTransaction) Delete(name string, key []byte) error {
// Move cursor to correct position.
c := b.cursor()
- c.Get(key)
+ c.Seek(key)
// Delete the node if we have a matching key.
c.node(t).del(key)
diff --git a/transaction.go b/transaction.go
index 54aae8c..3951cd8 100644
--- a/transaction.go
+++ b/transaction.go
@@ -1,5 +1,9 @@
package bolt
+import (
+ "bytes"
+)
+
// Transaction represents a read-only transaction on the database.
// It can be used for retrieving values for keys as well as creating cursors for
// iterating over the data.
@@ -90,7 +94,12 @@ func (t *Transaction) Get(name string, key []byte) (value []byte, err error) {
if err != nil {
return nil, err
}
- return c.Get(key), nil
+ k, v := c.Seek(key)
+ // If our target node isn't the same key as what's passed in then return nil.
+ if !bytes.Equal(key, k) {
+ return nil, nil
+ }
+ return v, nil
}
// ForEach executes a function for each key/value pair in a bucket.