mirror of
https://github.com/etcd-io/bbolt.git
synced 2025-05-31 11:42:30 +00:00
commit
a2535f64ec
19
cursor.go
19
cursor.go
@ -111,6 +111,25 @@ func (c *Cursor) Seek(seek []byte) (key []byte, value []byte) {
|
|||||||
return k, v
|
return k, v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete removes the current key/value under the cursor from the bucket.
|
||||||
|
// Delete fails if current key/value is a bucket or if the transaction is not writable.
|
||||||
|
func (c *Cursor) Delete() error {
|
||||||
|
if c.bucket.tx.db == nil {
|
||||||
|
return ErrTxClosed
|
||||||
|
} else if !c.bucket.Writable() {
|
||||||
|
return ErrTxNotWritable
|
||||||
|
}
|
||||||
|
|
||||||
|
key, _, flags := c.keyValue()
|
||||||
|
// Return an error if current value is a bucket.
|
||||||
|
if (flags & bucketLeafFlag) != 0 {
|
||||||
|
return ErrIncompatibleValue
|
||||||
|
}
|
||||||
|
c.node().del(key)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// seek moves the cursor to a given key and returns it.
|
// seek moves the cursor to a given key and returns it.
|
||||||
// If the key does not exist then the next key is used.
|
// If the key does not exist then the next key is used.
|
||||||
func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
|
func (c *Cursor) seek(seek []byte) (key []byte, value []byte, flags uint32) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package bolt
|
package bolt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
@ -67,6 +68,45 @@ func TestCursor_Seek(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCursor_Delete(t *testing.T) {
|
||||||
|
withOpenDB(func(db *DB, path string) {
|
||||||
|
var count = 1000
|
||||||
|
|
||||||
|
// Insert every other key between 0 and $count.
|
||||||
|
db.Update(func(tx *Tx) error {
|
||||||
|
b, _ := tx.CreateBucket([]byte("widgets"))
|
||||||
|
for i := 0; i < count; i += 1 {
|
||||||
|
k := make([]byte, 8)
|
||||||
|
binary.BigEndian.PutUint64(k, uint64(i))
|
||||||
|
b.Put(k, make([]byte, 100))
|
||||||
|
}
|
||||||
|
b.CreateBucket([]byte("sub"))
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
db.Update(func(tx *Tx) error {
|
||||||
|
c := tx.Bucket([]byte("widgets")).Cursor()
|
||||||
|
bound := make([]byte, 8)
|
||||||
|
binary.BigEndian.PutUint64(bound, uint64(count/2))
|
||||||
|
for key, _ := c.First(); bytes.Compare(key, bound) < 0; key, _ = c.Next() {
|
||||||
|
if err := c.Delete(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Seek([]byte("sub"))
|
||||||
|
err := c.Delete()
|
||||||
|
assert.Equal(t, err, ErrIncompatibleValue)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
db.View(func(tx *Tx) error {
|
||||||
|
b := tx.Bucket([]byte("widgets"))
|
||||||
|
assert.Equal(t, b.Stats().KeyN, count/2+1)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure that a Tx cursor can seek to the appropriate keys when there are a
|
// Ensure that a Tx cursor can seek to the appropriate keys when there are a
|
||||||
// large number of keys. This test also checks that seek will always move
|
// large number of keys. This test also checks that seek will always move
|
||||||
// forward to the next key.
|
// forward to the next key.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user