Skip to content

Commit 5a67161

Browse files
committed
Update namespace empty check to use buckets
Directly get and check whether a bucket is empty. This prevents unnecessarily loading all records of the buckets into memory just to check existence. Also added checks for content and snapshots. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
1 parent c59bc7e commit 5a67161

File tree

2 files changed

+34
-28
lines changed

2 files changed

+34
-28
lines changed

metadata/buckets.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,8 @@ func imagesBucketPath(namespace string) [][]byte {
106106
return [][]byte{bucketKeyVersion, []byte(namespace), bucketKeyObjectImages}
107107
}
108108

109-
func withImagesBucket(tx *bolt.Tx, namespace string, fn func(bkt *bolt.Bucket) error) error {
110-
bkt, err := createBucketIfNotExists(tx, imagesBucketPath(namespace)...)
111-
if err != nil {
112-
return err
113-
}
114-
115-
return fn(bkt)
109+
func createImagesBucket(tx *bolt.Tx, namespace string) (*bolt.Bucket, error) {
110+
return createBucketIfNotExists(tx, imagesBucketPath(namespace)...)
116111
}
117112

118113
func getImagesBucket(tx *bolt.Tx, namespace string) *bolt.Bucket {
@@ -143,6 +138,10 @@ func createSnapshotterBucket(tx *bolt.Tx, namespace, snapshotter string) (*bolt.
143138
return bkt, nil
144139
}
145140

141+
func getSnapshottersBucket(tx *bolt.Tx, namespace string) *bolt.Bucket {
142+
return getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectSnapshots)
143+
}
144+
146145
func getSnapshotterBucket(tx *bolt.Tx, namespace, snapshotter string) *bolt.Bucket {
147146
return getBucket(tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectSnapshots, []byte(snapshotter))
148147
}

metadata/namespaces.go

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -133,31 +133,38 @@ func (s *namespaceStore) Delete(ctx context.Context, namespace string) error {
133133
}
134134

135135
func (s *namespaceStore) namespaceEmpty(ctx context.Context, namespace string) (bool, error) {
136-
ctx = namespaces.WithNamespace(ctx, namespace)
137-
138-
// need to check the various object stores.
139-
140-
imageStore := NewImageStore(s.tx)
141-
images, err := imageStore.List(ctx)
142-
if err != nil {
143-
return false, err
144-
}
145-
if len(images) > 0 {
146-
return false, nil
136+
// Get all data buckets
137+
buckets := []*bolt.Bucket{
138+
getImagesBucket(s.tx, namespace),
139+
getBlobsBucket(s.tx, namespace),
140+
getContainersBucket(s.tx, namespace),
141+
}
142+
if snbkt := getSnapshottersBucket(s.tx, namespace); snbkt != nil {
143+
if err := snbkt.ForEach(func(k, v []byte) error {
144+
if v == nil {
145+
buckets = append(buckets, snbkt.Bucket(k))
146+
}
147+
return nil
148+
}); err != nil {
149+
return false, err
150+
}
147151
}
148152

149-
containerStore := NewContainerStore(s.tx)
150-
containers, err := containerStore.List(ctx)
151-
if err != nil {
152-
return false, err
153+
// Ensure data buckets are empty
154+
for _, bkt := range buckets {
155+
if !isBucketEmpty(bkt) {
156+
return false, nil
157+
}
153158
}
154159

155-
if len(containers) > 0 {
156-
return false, nil
157-
}
160+
return true, nil
161+
}
158162

159-
// TODO(stevvooe): Need to add check for content store, as well. Still need
160-
// to make content store namespace aware.
163+
func isBucketEmpty(bkt *bolt.Bucket) bool {
164+
if bkt == nil {
165+
return true
166+
}
161167

162-
return true, nil
168+
k, _ := bkt.Cursor().First()
169+
return k == nil
163170
}

0 commit comments

Comments
 (0)