mirror of https://github.com/etcd-io/bbolt.git
Add bucket reclamation.
After RWTransaction.DeleteBucket() is called, all pages related to the bucket are moved to the freelist for that transaction.pull/34/head
parent
0209ad2ed4
commit
9abced434f
|
@ -63,14 +63,18 @@ func (t *RWTransaction) CreateBucketIfNotExists(name string) error {
|
||||||
// DeleteBucket deletes a bucket.
|
// DeleteBucket deletes a bucket.
|
||||||
// Returns an error if the bucket cannot be found.
|
// Returns an error if the bucket cannot be found.
|
||||||
func (t *RWTransaction) DeleteBucket(name string) error {
|
func (t *RWTransaction) DeleteBucket(name string) error {
|
||||||
if b := t.Bucket(name); b == nil {
|
b := t.Bucket(name)
|
||||||
|
if b == nil {
|
||||||
return ErrBucketNotFound
|
return ErrBucketNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove from buckets page.
|
// Remove from buckets page.
|
||||||
t.buckets.del(name)
|
t.buckets.del(name)
|
||||||
|
|
||||||
// TODO(benbjohnson): Free all pages.
|
// Free all pages.
|
||||||
|
t.forEachPage(b.root, 0, func(p *page, depth int) {
|
||||||
|
t.db.freelist.free(t.id(), p)
|
||||||
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ func TestRWTransactionCreateBucketIfNotExists(t *testing.T) {
|
||||||
withOpenDB(func(db *DB, path string) {
|
withOpenDB(func(db *DB, path string) {
|
||||||
assert.NoError(t, db.CreateBucketIfNotExists("widgets"))
|
assert.NoError(t, db.CreateBucketIfNotExists("widgets"))
|
||||||
assert.NoError(t, db.CreateBucketIfNotExists("widgets"))
|
assert.NoError(t, db.CreateBucketIfNotExists("widgets"))
|
||||||
|
assert.Equal(t, db.CreateBucketIfNotExists(""), ErrBucketNameRequired)
|
||||||
|
|
||||||
// Read the bucket through a separate transaction.
|
// Read the bucket through a separate transaction.
|
||||||
b, err := db.Bucket("widgets")
|
b, err := db.Bucket("widgets")
|
||||||
|
@ -113,12 +114,17 @@ func TestRWTransactionDeleteBucket(t *testing.T) {
|
||||||
db.CreateBucket("widgets")
|
db.CreateBucket("widgets")
|
||||||
db.Put("widgets", []byte("foo"), []byte("bar"))
|
db.Put("widgets", []byte("foo"), []byte("bar"))
|
||||||
|
|
||||||
|
b, _ := db.Bucket("widgets")
|
||||||
|
|
||||||
// Delete the bucket and make sure we can't get the value.
|
// Delete the bucket and make sure we can't get the value.
|
||||||
assert.NoError(t, db.DeleteBucket("widgets"))
|
assert.NoError(t, db.DeleteBucket("widgets"))
|
||||||
value, err := db.Get("widgets", []byte("foo"))
|
value, err := db.Get("widgets", []byte("foo"))
|
||||||
assert.Equal(t, err, ErrBucketNotFound)
|
assert.Equal(t, err, ErrBucketNotFound)
|
||||||
assert.Nil(t, value)
|
assert.Nil(t, value)
|
||||||
|
|
||||||
|
// Verify that the bucket's page is free.
|
||||||
|
assert.Equal(t, db.freelist.all(), []pgid{b.root})
|
||||||
|
|
||||||
// Create the bucket again and make sure there's not a phantom value.
|
// Create the bucket again and make sure there's not a phantom value.
|
||||||
assert.NoError(t, db.CreateBucket("widgets"))
|
assert.NoError(t, db.CreateBucket("widgets"))
|
||||||
value, err = db.Get("widgets", []byte("foo"))
|
value, err = db.Get("widgets", []byte("foo"))
|
||||||
|
|
Loading…
Reference in New Issue