aboutsummaryrefslogtreecommitdiff
path: root/src/dedo.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/dedo.go')
-rw-r--r--src/dedo.go70
1 files changed, 41 insertions, 29 deletions
diff --git a/src/dedo.go b/src/dedo.go
index af29fdd..8ec8b41 100644
--- a/src/dedo.go
+++ b/src/dedo.go
@@ -77,13 +77,13 @@ type BucketI interface{
ForEach(func([]byte, []byte) error) error
CreateBucket([]byte) (BucketI, error)
DeleteBucket([]byte) error
- Bucket([]byte) BucketI
+ Bucket([]byte) (BucketI, error)
NextSequence() (uint64, error)
Cursor() CursorI
}
type SnapshotI interface{
- Bucket([]byte) BucketI
+ Bucket([]byte) (BucketI, error)
Cursor() CursorI
ForEach(func([]byte, BucketI) error) error
@@ -92,7 +92,7 @@ type SnapshotI interface{
}
type TransactionI interface{
- Bucket([]byte) BucketI
+ Bucket([]byte) (BucketI, error)
Cursor() CursorI
ForEach(func([]byte, BucketI) error) error
@@ -458,6 +458,8 @@ var (
/// These errors can occur when putting or deleting a value or a bucket.
///
+ ErrBucketBadFlag = errors.New("bucket does not have bucketLeafFlag")
+
/// ErrBucketNotFound is returned when trying to access a bucket that
/// has not been created yet.
ErrBucketNotFound = errors.New("bucket not found")
@@ -620,11 +622,11 @@ func (b *bucketT) Cursor() CursorI {
/// bucketT.Bucket() retrieves a nested bucket by name. Returns nil if the
/// bucket does not exist. The bucket instance is only valid for the lifetime
/// of the transaction.
-func bucketGetNested(b *bucketT, name []byte) *bucketT {
+func bucketGetNested(b *bucketT, name []byte) (*bucketT, error) {
if b.buckets != nil {
child := b.buckets[string(name)]
if child != nil {
- return child
+ return child, nil
}
}
@@ -633,8 +635,12 @@ func bucketGetNested(b *bucketT, name []byte) *bucketT {
k, v, flags := c.seek(name)
// Return nil if the key doesn't exist or it is not a bucket.
- if !bytes.Equal(name, k) || (flags&bucketLeafFlag) == 0 {
- return nil
+ if !bytes.Equal(name, k) {
+ return nil, ErrBucketNotFound
+ }
+
+ if (flags & bucketLeafFlag) == 0 {
+ return nil, ErrBucketBadFlag
}
// Otherwise create a bucket and cache it.
@@ -643,10 +649,10 @@ func bucketGetNested(b *bucketT, name []byte) *bucketT {
b.buckets[string(name)] = child
}
- return child
+ return child, nil
}
-func (b *bucketT) Bucket(name []byte) BucketI {
+func (b *bucketT) Bucket(name []byte) (BucketI, error) {
return bucketGetNested(b, name)
}
@@ -714,7 +720,7 @@ func bucketCreateBucket(b *bucketT, key []byte) (*bucketT, error) {
// the tx.
b.page = nil
- return bucketGetNested(b, key), nil
+ return bucketGetNested(b, key)
}
func (b *bucketT) CreateBucket(key []byte) (BucketI, error) {
@@ -728,7 +734,7 @@ func (b *bucketT) CreateBucket(key []byte) (BucketI, error) {
func bucketCreateBucketIfNotExists(b *bucketT, key []byte) (*bucketT, error) {
child, err := bucketCreateBucket(b, key)
if err == ErrBucketExists {
- return bucketGetNested(b, key), nil
+ return bucketGetNested(b, key)
} else if err != nil {
return nil, err
}
@@ -760,8 +766,12 @@ func bucketDeleteBucket(b *bucketT, key []byte) error {
}
// Recursively delete all child buckets.
- child := bucketGetNested(b, key)
- err := child.ForEach(func(k, v []byte) error {
+ child, err := bucketGetNested(b, key)
+ if err != nil {
+ return err
+ }
+
+ err = child.ForEach(func(k, v []byte) error {
if v == nil {
err := child.DeleteBucket(k)
if err != nil {
@@ -3580,11 +3590,11 @@ func (tx *transactionT) Cursor() CursorI {
/// transactionT.Bucket() retrieves a bucket by name. Returns nil if the bucket does not
/// exist. The bucket instance is only valid for the lifetime of the
/// transaction.
-func txBucket(tx *transactionT, name []byte) *bucketT {
+func txBucket(tx *transactionT, name []byte) (*bucketT, error) {
return bucketGetNested(&tx.root, name)
}
-func (tx *transactionT) Bucket(name []byte) BucketI {
+func (tx *transactionT) Bucket(name []byte) (BucketI, error) {
return txBucket(tx, name)
}
@@ -3627,11 +3637,11 @@ func (tx *transactionT) DeleteBucket(name []byte) error {
/// error is returned to the caller.
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))
+ bucket, err := tx.root.Bucket(k)
if err != nil {
return err
}
- return nil
+ return fn(k, bucket)
})
}
@@ -3923,10 +3933,12 @@ func (tx *transactionT) checkBucket(
// Check each bucket within this bucket.
_ = b.ForEach(func(k, v []byte) error {
- child := bucketGetNested(b, k)
- if child != nil {
- tx.checkBucket(child, reachable, freed, ch)
+ child, err := bucketGetNested(b, k)
+ if err != nil{
+ return nil
}
+
+ tx.checkBucket(child, reachable, freed, ch)
return nil
})
}
@@ -4107,9 +4119,9 @@ func checkExec(args argsT, db DatabaseI, _r io.Reader, _w io.Writer) error {
func getExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
return db.View(func(snapshot SnapshotI) error {
- bucket := snapshot.Bucket(args.bucket)
- if bucket == nil {
- return ErrBucketNotFound
+ bucket, err := snapshot.Bucket(args.bucket)
+ if err != nil {
+ return err
}
value := bucket.Get(args.key)
@@ -4135,9 +4147,9 @@ func setExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
func rmExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
return db.Update(func(tx TransactionI) error {
- bucket := tx.Bucket(args.bucket)
- if bucket == nil {
- return ErrBucketNotFound
+ bucket, err := tx.Bucket(args.bucket)
+ if err != nil {
+ return err
}
return bucket.Delete(args.key)
@@ -4156,9 +4168,9 @@ func listExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
})
}
- bucket := snapshot.Bucket(args.bucket)
- if bucket == nil {
- return ErrBucketNotFound
+ bucket, err := snapshot.Bucket(args.bucket)
+ if err != nil {
+ return err
}
return bucket.ForEach(func(key []byte, value []byte) error {