diff --git a/gc/gc.go b/gc/gc.go index 4f71cb305..079a6eae9 100644 --- a/gc/gc.go +++ b/gc/gc.go @@ -59,6 +59,8 @@ type Stats interface { // // We can probably use this to inform a design for incremental GC by injecting // callbacks to the set modification algorithms. +// +// https://en.wikipedia.org/wiki/Tracing_garbage_collection#Tri-color_marking func Tricolor(roots []Node, refs func(ref Node) ([]Node, error)) (map[Node]struct{}, error) { var ( grays []Node // maintain a gray "stack" diff --git a/metadata/content.go b/metadata/content.go index e024f9a50..66d0ee263 100644 --- a/metadata/content.go +++ b/metadata/content.go @@ -772,6 +772,7 @@ func writeExpireAt(expire time.Time, bkt *bolt.Bucket) error { return bkt.Put(bucketKeyExpireAt, expireAt) } +// garbageCollect removes all contents that are no longer used. func (cs *contentStore) garbageCollect(ctx context.Context) (d time.Duration, err error) { cs.l.Lock() t1 := time.Now() diff --git a/metadata/db.go b/metadata/db.go index c5a2f2eb4..2d9cbf31a 100644 --- a/metadata/db.go +++ b/metadata/db.go @@ -277,7 +277,7 @@ func (s GCStats) Elapsed() time.Duration { return s.MetaD } -// GarbageCollect starts garbage collection +// GarbageCollect removes resources (snapshots, contents, ...) that are no longer used. func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { m.wlock.Lock() t1 := time.Now() @@ -363,6 +363,7 @@ func (m *DB) GarbageCollect(ctx context.Context) (gc.Stats, error) { return stats, err } +// getMarked returns all resources that are used. func (m *DB) getMarked(ctx context.Context) (map[gc.Node]struct{}, error) { var marked map[gc.Node]struct{} if err := m.db.View(func(tx *bolt.Tx) error { diff --git a/metadata/gc.go b/metadata/gc.go index b526d995d..60bf410a6 100644 --- a/metadata/gc.go +++ b/metadata/gc.go @@ -58,6 +58,8 @@ var ( labelGCFlat = []byte("containerd.io/gc.flat") ) +// scanRoots sends the given channel "root" resources that are certainly used. +// The caller could look the references of the resources to find all resources that are used. func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { @@ -276,6 +278,7 @@ func scanRoots(ctx context.Context, tx *bolt.Tx, nc chan<- gc.Node) error { return cerr } +// references finds the resources that are reachable from the given node. func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node)) error { switch node.Type { case ResourceContent: @@ -328,6 +331,7 @@ func references(ctx context.Context, tx *bolt.Tx, node gc.Node, fn func(gc.Node) return nil } +// scanAll finds all resources regardless whether the resources are used or not. func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc.Node) error) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { @@ -408,6 +412,7 @@ func scanAll(ctx context.Context, tx *bolt.Tx, fn func(ctx context.Context, n gc return nil } +// remove all buckets for the given node. func remove(ctx context.Context, tx *bolt.Tx, node gc.Node) error { v1bkt := tx.Bucket(bucketKeyVersion) if v1bkt == nil { diff --git a/metadata/snapshot.go b/metadata/snapshot.go index 0c267060d..348602093 100644 --- a/metadata/snapshot.go +++ b/metadata/snapshot.go @@ -790,6 +790,7 @@ func validateSnapshot(info *snapshots.Info) error { return nil } +// garbageCollect removes all snapshots that are no longer used. func (s *snapshotter) garbageCollect(ctx context.Context) (d time.Duration, err error) { s.l.Lock() t1 := time.Now()