diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 08046371..ccac1f66 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -67,6 +67,8 @@ type RemoteCache struct { records map[digest.Digest]*Item // size is the cache record capacity of target layers. size int + // updateCount records the number of new caches added in one conversion. + updateCount int } func New(ctx context.Context, ref string, size int, pvd Provider) (context.Context, *RemoteCache) { @@ -157,6 +159,9 @@ func Get(ctx context.Context, dgst digest.Digest) (*RemoteCache, *ocispec.Descri func Set(ctx context.Context, source, target ocispec.Descriptor) { rc, ok := ctx.Value(cacheKey{}).(*RemoteCache) if ok { + if rc.get(source.Digest) == nil { + rc.updateCount++ + } rc.set(source, target) } } @@ -456,3 +461,34 @@ func appendLayers(orgDescs, newDescs []ocispec.Descriptor, size int) []ocispec.D } return mergedLayers } + +// HitCount returns the hit info of cache layers in a conversion. +func (rc *RemoteCache) HitInfo(ctx context.Context, desc ocispec.Descriptor, platform platforms.MatchComparer) (string, error) { + maniDescs := []ocispec.Descriptor{} + switch desc.MediaType { + case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest: + maniDescs = append(maniDescs, desc) + case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex: + descs, err := utils.GetManifests(ctx, rc.provider.ContentStore(), desc, platform) + if err != nil { + return "", err + } + maniDescs = append(maniDescs, descs...) + } + hitCount := 0 + cacheCount := 0 + for _, maniDesc := range maniDescs { + manifest := ocispec.Manifest{} + _, err := utils.ReadJSON(ctx, rc.provider.ContentStore(), &manifest, maniDesc) + if err != nil { + return "", errors.Wrap(err, "read manifest") + } + cacheCount += len(manifest.Layers) + for _, sourceLayer := range manifest.Layers { + if item := rc.get(sourceLayer.Digest); item != nil { + hitCount++ + } + } + } + return fmt.Sprintf("%d/%d", (hitCount - rc.updateCount), cacheCount), nil +} diff --git a/pkg/converter/converter.go b/pkg/converter/converter.go index 93185501..c8ff518e 100644 --- a/pkg/converter/converter.go +++ b/pkg/converter/converter.go @@ -142,7 +142,19 @@ func (cvt *Converter) Convert(ctx context.Context, source, target, cacheRef stri if err := metric.SetSourceImageSize(ctx, cvt, source); err != nil { return nil, errors.Wrap(err, "get source image size") } - logger.Infof("pulled image %s, elapse %s", source, metric.SourcePullElapsed) + cacheHit := "" + if cache != nil { + sourceImage, err := cvt.provider.Image(ctx, source) + if err != nil { + return nil, errors.Wrap(err, "get source image") + } + hitInfo, err := cache.HitInfo(ctx, *sourceImage, cvt.platformMC) + if err != nil { + logger.Warnf("failed to get cache hit count: %s", err.Error()) + } + cacheHit = fmt.Sprintf("(cached %s)", hitInfo) + } + logger.Infof("pulled image %s%s, elapse %s", source, cacheHit, metric.SourcePullElapsed) logger.Infof("converting image %s", source) start = time.Now() @@ -158,7 +170,19 @@ func (cvt *Converter) Convert(ctx context.Context, source, target, cacheRef stri if err := metric.SetTargetImageSize(ctx, cvt, desc); err != nil { return nil, errors.Wrap(err, "get target image size") } - logger.Infof("converted image %s, elapse %s", target, metric.ConversionElapsed) + cacheHit = "" + if cache != nil { + sourceImage, err := cvt.provider.Image(ctx, source) + if err != nil { + return nil, errors.Wrap(err, "get source image") + } + hitInfo, err := cache.HitInfo(ctx, *sourceImage, cvt.platformMC) + if err != nil { + logger.Warnf("failed to get cache hit count: %s", err.Error()) + } + cacheHit = fmt.Sprintf("(cached %s)", hitInfo) + } + logger.Infof("converted image %s%s, elapse %s", target, cacheHit, metric.ConversionElapsed) if cache != nil { sourceImage, err := cvt.provider.Image(ctx, source)