bolt
bolt copied to clipboard
Provide safe method to delete a nested bucket during iteration
Currently, there is no safe way to delete buckets during iteration. This is because it's not safe to delete/add new keys or buckets during ForEach iteration, the Delete method on a Cursor can't be used for buckets, and there is no DeleteBucket method on a Cursor. As a result, code to remove all nested buckets and keys in a given bucket ends up looking like the following:
// Remove all the keys using a cursor while also generating a
// list of buckets. It's not safe to remove keys during ForEach
// iteration nor is it safe to remove buckets during cursor
// iteration, so this dual approach is needed.
var bucketNames [][]byte
cursor := bucket.Cursor()
for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
if v != nil {
if err := cursor.Delete(); err != nil {
return err
}
} else {
bucketNames = append(bucketNames, k)
}
}
// Remove the buckets.
for _, k := range bucketNames {
if err := bucket.DeleteBucket(k); err != nil {
return err
}
}
I would suggest either adding a DeleteBucket method to the Cursor type which provides the same safety guarantee Delete provides for keys during cursor iteration, or modifying Delete to work with both keys and buckets.