aboutsummaryrefslogtreecommitdiff
path: root/src/dedo.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/dedo.go')
-rw-r--r--src/dedo.go76
1 files changed, 46 insertions, 30 deletions
diff --git a/src/dedo.go b/src/dedo.go
index d8655bb..af29fdd 100644
--- a/src/dedo.go
+++ b/src/dedo.go
@@ -63,28 +63,44 @@ import (
type CursorI interface{
First() ([]byte, []byte)
+ Last() ([]byte, []byte)
Next() ([]byte, []byte)
+ Prev() ([]byte, []byte)
+ Seek([]byte) ([]byte, []byte)
+ Delete() error
+}
+
+type BucketI interface{
+ Get([]byte) []byte
+ Put([]byte, []byte) error
+ Delete([]byte) error
+ ForEach(func([]byte, []byte) error) error
+ CreateBucket([]byte) (BucketI, error)
+ DeleteBucket([]byte) error
+ Bucket([]byte) BucketI
+ NextSequence() (uint64, error)
+ Cursor() CursorI
}
type SnapshotI interface{
- Bucket([]byte) *bucketT
+ Bucket([]byte) BucketI
Cursor() CursorI
- ForEach(func([]byte, *bucketT) error) error
+ ForEach(func([]byte, BucketI) error) error
WriteTo(io.Writer) (int64, error)
Check() <-chan error
}
type TransactionI interface{
- Bucket([]byte) *bucketT
+ Bucket([]byte) BucketI
Cursor() CursorI
- ForEach(func([]byte, *bucketT) error) error
+ ForEach(func([]byte, BucketI) error) error
WriteTo(io.Writer) (int64, error)
Check() <-chan error
- CreateBucket ([]byte) (*bucketT, error)
- CreateBucketIfNotExists([]byte) (*bucketT, error)
+ CreateBucket ([]byte) (BucketI, error)
+ CreateBucketIfNotExists([]byte) (BucketI, error)
DeleteBucket([]byte) error
OnCommit(func())
}
@@ -597,7 +613,7 @@ func bucketCursor(b *bucketT) *cursorT {
}
}
-func (b *bucketT) Cursor() *cursorT {
+func (b *bucketT) Cursor() CursorI {
return bucketCursor(b)
}
@@ -613,7 +629,7 @@ func bucketGetNested(b *bucketT, name []byte) *bucketT {
}
// Move cursor to key.
- c := b.Cursor()
+ c := bucketCursor(b)
k, v, flags := c.seek(name)
// Return nil if the key doesn't exist or it is not a bucket.
@@ -630,7 +646,7 @@ func bucketGetNested(b *bucketT, name []byte) *bucketT {
return child
}
-func (b *bucketT) Bucket(name []byte) *bucketT {
+func (b *bucketT) Bucket(name []byte) BucketI {
return bucketGetNested(b, name)
}
@@ -670,7 +686,7 @@ func bucketCreateBucket(b *bucketT, key []byte) (*bucketT, error) {
}
// Move cursor to correct position.
- c := b.Cursor()
+ c := bucketCursor(b)
k, _, flags := c.seek(key)
// Return an error if there is an existing key.
@@ -698,10 +714,10 @@ func bucketCreateBucket(b *bucketT, key []byte) (*bucketT, error) {
// the tx.
b.page = nil
- return b.Bucket(key), nil
+ return bucketGetNested(b, key), nil
}
-func (b *bucketT) CreateBucket(key []byte) (*bucketT, error) {
+func (b *bucketT) CreateBucket(key []byte) (BucketI, error) {
return bucketCreateBucket(b, key)
}
@@ -710,9 +726,9 @@ func (b *bucketT) CreateBucket(key []byte) (*bucketT, error) {
/// blank, or if the bucket name is too long. The bucket instance is only valid
/// for the lifetime of the transaction.
func bucketCreateBucketIfNotExists(b *bucketT, key []byte) (*bucketT, error) {
- child, err := b.CreateBucket(key)
+ child, err := bucketCreateBucket(b, key)
if err == ErrBucketExists {
- return b.Bucket(key), nil
+ return bucketGetNested(b, key), nil
} else if err != nil {
return nil, err
}
@@ -733,7 +749,7 @@ func bucketDeleteBucket(b *bucketT, key []byte) error {
}
// Move cursor to correct position.
- c := b.Cursor()
+ c := bucketCursor(b)
k, _, flags := c.seek(key)
// Return an error if bucket doesn't exist or is not a bucket.
@@ -744,7 +760,7 @@ func bucketDeleteBucket(b *bucketT, key []byte) error {
}
// Recursively delete all child buckets.
- child := b.Bucket(key)
+ child := bucketGetNested(b, key)
err := child.ForEach(func(k, v []byte) error {
if v == nil {
err := child.DeleteBucket(k)
@@ -780,7 +796,7 @@ func (b *bucketT) DeleteBucket(key []byte) error {
/// value if the key does not exist or if the key is a nested bucket. The
/// returned value is only valid for the life of the transaction.
func bucketGet(b *bucketT, key []byte) []byte {
- k, v, flags := b.Cursor().seek(key)
+ k, v, flags := bucketCursor(b).seek(key)
// Return nil if this is a bucket.
if (flags & bucketLeafFlag) != 0 {
@@ -818,7 +834,7 @@ func bucketPut(b *bucketT, key []byte, value []byte) error {
}
// Move cursor to correct position.
- c := b.Cursor()
+ c := bucketCursor(b)
k, _, flags := c.seek(key)
// Return an error if there is an existing key with a bucket value.
@@ -848,7 +864,7 @@ func bucketDelete(b *bucketT, key []byte) error {
}
// Move cursor to correct position.
- c := b.Cursor()
+ c := bucketCursor(b)
_, _, flags := c.seek(key)
// Return an error if there is already existing bucket value.
@@ -998,7 +1014,7 @@ func (b *bucketT) spill() error {
}
// Update parent node.
- c := b.Cursor()
+ c := bucketCursor(b)
k, _, flags := c.seek([]byte(name))
if !bytes.Equal([]byte(name), k) {
panic(fmt.Sprintf(
@@ -3554,7 +3570,7 @@ func (tx *transactionT) Size() int64 {
/// buckets. The cursor is only valid as long as the transaction is open. Do
/// not use a cursor after the transaction is closed.
func txCursor(tx *transactionT) *cursorT {
- return tx.root.Cursor()
+ return bucketCursor(&tx.root)
}
func (tx *transactionT) Cursor() CursorI {
@@ -3565,10 +3581,10 @@ func (tx *transactionT) Cursor() CursorI {
/// exist. The bucket instance is only valid for the lifetime of the
/// transaction.
func txBucket(tx *transactionT, name []byte) *bucketT {
- return tx.root.Bucket(name)
+ return bucketGetNested(&tx.root, name)
}
-func (tx *transactionT) Bucket(name []byte) *bucketT {
+func (tx *transactionT) Bucket(name []byte) BucketI {
return txBucket(tx, name)
}
@@ -3577,10 +3593,10 @@ func (tx *transactionT) Bucket(name []byte) *bucketT {
/// long. The bucket instance is only valid for the lifetime of the
/// transaction.
func txCreateBucket(tx *transactionT, name []byte) (*bucketT, error) {
- return tx.root.CreateBucket(name)
+ return bucketCreateBucket(&tx.root, name)
}
-func (tx *transactionT) CreateBucket(name []byte) (*bucketT, error) {
+func (tx *transactionT) CreateBucket(name []byte) (BucketI, error) {
return txCreateBucket(tx, name)
}
@@ -3592,7 +3608,7 @@ func txCreateBucketIfNotExists(tx *transactionT, name []byte) (*bucketT, error)
return tx.root.CreateBucketIfNotExists(name)
}
-func (tx *transactionT) CreateBucketIfNotExists(name []byte) (*bucketT, error) {
+func (tx *transactionT) CreateBucketIfNotExists(name []byte) (BucketI, error) {
return txCreateBucketIfNotExists(tx, name)
}
@@ -3609,7 +3625,7 @@ func (tx *transactionT) DeleteBucket(name []byte) error {
/// transactionT.ForEach() executes a function for each bucket in the root. If the
/// provided function returns an error then the iteration is stopped and the
/// error is returned to the caller.
-func txForEach(tx *transactionT, fn func([]byte, *bucketT) error) error {
+func txForEach(tx *transactionT, fn func([]byte, BucketI) error) error {
return tx.root.ForEach(func(k []byte, v []byte) error {
err := fn(k, tx.root.Bucket(k))
if err != nil {
@@ -3619,7 +3635,7 @@ func txForEach(tx *transactionT, fn func([]byte, *bucketT) error) error {
})
}
-func (tx *transactionT) ForEach(fn func([]byte, *bucketT) error) error {
+func (tx *transactionT) ForEach(fn func([]byte, BucketI) error) error {
return txForEach(tx, fn)
}
@@ -3907,7 +3923,7 @@ func (tx *transactionT) checkBucket(
// Check each bucket within this bucket.
_ = b.ForEach(func(k, v []byte) error {
- child := b.Bucket(k)
+ child := bucketGetNested(b, k)
if child != nil {
tx.checkBucket(child, reachable, freed, ch)
}
@@ -4133,7 +4149,7 @@ func listExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
if len(args.bucket) == 0 {
return snapshot.ForEach(func(
name []byte,
- bucket *bucketT,
+ bucket BucketI,
) error {
fmt.Fprintf(w, "%s\n", string(name))
return nil