aboutsummaryrefslogtreecommitdiff
path: root/src/dedo.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/dedo.go')
-rw-r--r--src/dedo.go130
1 files changed, 93 insertions, 37 deletions
diff --git a/src/dedo.go b/src/dedo.go
index ae15ff2..f308b71 100644
--- a/src/dedo.go
+++ b/src/dedo.go
@@ -71,39 +71,46 @@ type CursorI interface{
Delete() error
}
-type BucketI interface{
+type ROBucketI interface{
Get([]byte) []byte
+ Cursor() CursorI
+ ForEach(func([]byte, []byte) error) error
+ ROBucket([]byte) (ROBucketI, error)
+}
+
+type RWBucketI interface{
+ Get([]byte) []byte
+ Cursor() CursorI
+ ForEach(func([]byte, []byte) error) error
+ RWBucket([]byte) (RWBucketI, error)
Put([]byte, []byte) error
Delete([]byte) error
- ForEach(func([]byte, []byte) error) error
- CreateBucket([]byte) (BucketI, error)
- CreateBucketIfNotExists([]byte) (BucketI, error)
+ CreateBucket([]byte) (RWBucketI, error)
+ CreateBucketIfNotExists([]byte) (RWBucketI, error)
DeleteBucket([]byte) error
- Bucket([]byte) (BucketI, error)
NextID() []byte
NextSequence() (uint64, error)
- Cursor() CursorI
}
type SnapshotI interface{
- Bucket([]byte) (BucketI, error)
+ ROBucket([]byte) (ROBucketI, error)
Cursor() CursorI
- ForEach(func([]byte, BucketI) error) error
+ ROForEach(func([]byte, ROBucketI) error) error
WriteTo(io.Writer) (int64, error)
Check() <-chan error
}
type TransactionI interface{
- Bucket([]byte) (BucketI, error)
+ RWBucket([]byte) (RWBucketI, error)
Cursor() CursorI
- ForEach(func([]byte, BucketI) error) error
+ RWForEach(func([]byte, RWBucketI) error) error
WriteTo(io.Writer) (int64, error)
Check() <-chan error
- CreateBucket ([]byte) (BucketI, error)
- CreateBucketIfNotExists([]byte) (BucketI, error)
+ CreateBucket ([]byte) (RWBucketI, error)
+ CreateBucketIfNotExists([]byte) (RWBucketI, error)
DeleteBucket([]byte) error
OnCommit(func())
}
@@ -678,7 +685,11 @@ func bucketGetNested(b *bucketT, name []byte) (*bucketT, error) {
return child, nil
}
-func (b *bucketT) Bucket(name []byte) (BucketI, error) {
+func (b *bucketT) ROBucket(name []byte) (ROBucketI, error) {
+ return bucketGetNested(b, name)
+}
+
+func (b *bucketT) RWBucket(name []byte) (RWBucketI, error) {
return bucketGetNested(b, name)
}
@@ -749,7 +760,7 @@ func bucketCreateBucket(b *bucketT, key []byte) (*bucketT, error) {
return bucketGetNested(b, key)
}
-func (b *bucketT) CreateBucket(key []byte) (BucketI, error) {
+func (b *bucketT) CreateBucket(key []byte) (RWBucketI, error) {
return bucketCreateBucket(b, key)
}
@@ -767,7 +778,7 @@ func bucketCreateBucketIfNotExists(b *bucketT, key []byte) (*bucketT, error) {
return child, nil
}
-func (b *bucketT) CreateBucketIfNotExists(key []byte) (BucketI, error) {
+func (b *bucketT) CreateBucketIfNotExists(key []byte) (RWBucketI, error) {
return bucketCreateBucketIfNotExists(b, key)
}
@@ -1811,7 +1822,10 @@ func (cursor *inMemoryCursorT) Delete() error {
return nil // FIXME
}
-func (bucket *inMemoryValueT) Bucket(name []byte) (BucketI, error) {
+func memBucketGetNested(
+ bucket *inMemoryValueT,
+ name []byte,
+) (*inMemoryValueT, error) {
if bucket.tx.root == nil {
return nil, ErrTxClosed
}
@@ -1828,7 +1842,15 @@ func (bucket *inMemoryValueT) Bucket(name []byte) (BucketI, error) {
return value, nil
}
-func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) {
+func (bucket *inMemoryValueT) ROBucket(name []byte) (ROBucketI, error) {
+ return memBucketGetNested(bucket, name)
+}
+
+func (bucket *inMemoryValueT) RWBucket(name []byte) (RWBucketI, error) {
+ return memBucketGetNested(bucket, name)
+}
+
+func (bucket *inMemoryValueT) CreateBucket(name []byte) (RWBucketI, error) {
if bucket.tx.root == nil {
return nil, ErrTxClosed
} else if !bucket.tx.writable {
@@ -1837,7 +1859,7 @@ func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) {
return nil, ErrBucketNameRequired
}
- _, err := bucket.Bucket(name)
+ _, err := bucket.RWBucket(name)
if err == nil {
return nil, ErrBucketExists
}
@@ -1853,7 +1875,7 @@ func (bucket *inMemoryValueT) CreateBucket(name []byte) (BucketI, error) {
return newBucket, nil
}
-func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (BucketI, error) {
+func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) {
if bucket.tx.root == nil {
return nil, ErrTxClosed
} else if !bucket.tx.writable {
@@ -1862,7 +1884,7 @@ func (bucket *inMemoryValueT) CreateBucketIfNotExists(name []byte) (BucketI, err
newBucket, err := bucket.CreateBucket(name)
if err == ErrBucketExists {
- return bucket.Bucket(name)
+ return bucket.RWBucket(name)
} else if err != nil {
return nil, err
}
@@ -1956,20 +1978,28 @@ func (bucket *inMemoryValueT) NextSequence() (uint64, error) {
return 0, nil // FIXME
}
-func (tx *inMemoryTxT) Bucket(name []byte) (BucketI, error) {
+func memTxBucket(tx *inMemoryTxT, name []byte) (*inMemoryValueT, error) {
if tx.root == nil {
return nil, ErrTxClosed
}
- return tx.root.Bucket(name)
+ return memBucketGetNested(tx.root, name)
+}
+
+func (tx *inMemoryTxT) ROBucket(name []byte) (ROBucketI, error) {
+ return memTxBucket(tx, name)
+}
+
+func (tx *inMemoryTxT) RWBucket(name []byte) (RWBucketI, error) {
+ return memTxBucket(tx, name)
}
-func (tx *inMemoryTxT) CreateBucket(name []byte) (BucketI, error) {
+func (tx *inMemoryTxT) CreateBucket(name []byte) (RWBucketI, error) {
// return tx.root.CreateBucket(name)
return nil, nil // FIXME
}
-func (tx *inMemoryTxT) CreateBucketIfNotExists(name []byte) (BucketI, error) {
+func (tx *inMemoryTxT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) {
return nil, nil // FIXME
}
@@ -1985,7 +2015,11 @@ func (tx *inMemoryTxT) DeleteBucket(name []byte) error {
return tx.root.DeleteBucket(name)
}
-func (tx *inMemoryTxT) ForEach(fn func([]byte, BucketI) error) error {
+func (tx *inMemoryTxT) ROForEach(fn func([]byte, ROBucketI) error) error {
+ return nil // FIXME
+}
+
+func (tx *inMemoryTxT) RWForEach(fn func([]byte, RWBucketI) error) error {
return nil // FIXME
}
@@ -3800,7 +3834,11 @@ func txBucket(tx *transactionT, name []byte) (*bucketT, error) {
return bucketGetNested(&tx.root, name)
}
-func (tx *transactionT) Bucket(name []byte) (BucketI, error) {
+func (tx *transactionT) ROBucket(name []byte) (ROBucketI, error) {
+ return txBucket(tx, name)
+}
+
+func (tx *transactionT) RWBucket(name []byte) (RWBucketI, error) {
return txBucket(tx, name)
}
@@ -3812,7 +3850,7 @@ func txCreateBucket(tx *transactionT, name []byte) (*bucketT, error) {
return bucketCreateBucket(&tx.root, name)
}
-func (tx *transactionT) CreateBucket(name []byte) (BucketI, error) {
+func (tx *transactionT) CreateBucket(name []byte) (RWBucketI, error) {
return txCreateBucket(tx, name)
}
@@ -3824,7 +3862,7 @@ func txCreateBucketIfNotExists(tx *transactionT, name []byte) (*bucketT, error)
return bucketCreateBucketIfNotExists(&tx.root, name)
}
-func (tx *transactionT) CreateBucketIfNotExists(name []byte) (BucketI, error) {
+func (tx *transactionT) CreateBucketIfNotExists(name []byte) (RWBucketI, error) {
return txCreateBucketIfNotExists(tx, name)
}
@@ -3841,9 +3879,13 @@ 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, BucketI) error) error {
+func txForEach[T any](
+ tx *transactionT,
+ fn func([]byte, T) error,
+ bucketFn func(*bucketT, []byte) (T, error),
+) error {
return tx.root.ForEach(func(k []byte, v []byte) error {
- bucket, err := tx.root.Bucket(k)
+ bucket, err := bucketFn(&tx.root, k)
if err != nil {
return err
}
@@ -3851,8 +3893,22 @@ func txForEach(tx *transactionT, fn func([]byte, BucketI) error) error {
})
}
-func (tx *transactionT) ForEach(fn func([]byte, BucketI) error) error {
- return txForEach(tx, fn)
+func (tx *transactionT) ROForEach(fn func([]byte, ROBucketI) error) error {
+ return txForEach(tx, fn, func(
+ bucket *bucketT,
+ name []byte,
+ ) (ROBucketI, error) {
+ return bucket.ROBucket(name)
+ })
+}
+
+func (tx *transactionT) RWForEach(fn func([]byte, RWBucketI) error) error {
+ return txForEach(tx, fn, func(
+ bucket *bucketT,
+ name []byte,
+ ) (RWBucketI, error) {
+ return bucket.RWBucket(name)
+ })
}
/// transactionT.OnCommit() adds a handler function to be executed after the transaction
@@ -4327,7 +4383,7 @@ 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, err := snapshot.Bucket(args.bucket)
+ bucket, err := snapshot.ROBucket(args.bucket)
if err != nil {
return err
}
@@ -4355,7 +4411,7 @@ 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, err := tx.Bucket(args.bucket)
+ bucket, err := tx.RWBucket(args.bucket)
if err != nil {
return err
}
@@ -4367,16 +4423,16 @@ func rmExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
func listExec(args argsT, db DatabaseI, r io.Reader, w io.Writer) error {
return db.View(func(snapshot SnapshotI) error {
if len(args.bucket) == 0 {
- return snapshot.ForEach(func(
+ return snapshot.ROForEach(func(
name []byte,
- bucket BucketI,
+ bucket ROBucketI,
) error {
fmt.Fprintf(w, "%s\n", string(name))
return nil
})
}
- bucket, err := snapshot.Bucket(args.bucket)
+ bucket, err := snapshot.ROBucket(args.bucket)
if err != nil {
return err
}