From e8dda70c417a78647ae31930acc0a98ecf5ad097 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Wed, 7 Jan 2026 21:36:47 +0900 Subject: [PATCH] internal/pkg: return reader for files This improves efficiency for cache hits. Signed-off-by: Ophestra --- internal/pkg/pkg.go | 26 ++++++++++++-------------- internal/pkg/pkg_test.go | 9 +++++++-- internal/pkg/tar.go | 14 +++++++++----- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go index 93677db..ab1f3e0 100644 --- a/internal/pkg/pkg.go +++ b/internal/pkg/pkg.go @@ -87,10 +87,11 @@ func (c *CureContext) Cure(a Artifact) ( return c.cache.Cure(a) } -// LoadData tries to load [File] from [Cache], and if that fails, obtains it via -// [File.Data] instead. Notably, it does not cure [File]. -func (c *CureContext) LoadData(f File) (data []byte, err error) { - return c.cache.loadData(f) +// OpenFile tries to load [File] from [Cache], and if that fails, obtains it via +// [File.Data] instead. Notably, it does not cure [File]. If err is nil, the +// caller is responsible for closing the resulting [io.ReadCloser]. +func (c *CureContext) OpenFile(f File) (r io.ReadCloser, err error) { + return c.cache.openFile(f) } // An Artifact is a read-only reference to a piece of data that may be created @@ -555,9 +556,8 @@ func (c *Cache) finaliseIdent( close(done) } -// loadData provides [CureContext.LoadData] for [Artifact.Cure]. -func (c *Cache) loadData(f File) (data []byte, err error) { - var r *os.File +// openFile provides [CureContext.OpenFile] for [Artifact.Cure]. +func (c *Cache) openFile(f File) (r io.ReadCloser, err error) { if kc, ok := f.(KnownChecksum); ok { c.checksumMu.RLock() r, err = os.Open(c.base.Append( @@ -578,13 +578,11 @@ func (c *Cache) loadData(f File) (data []byte, err error) { if !errors.Is(err, os.ErrNotExist) { return } - return f.Data() - } - - data, err = io.ReadAll(r) - closeErr := r.Close() - if err == nil { - err = closeErr + var data []byte + if data, err = f.Data(); err != nil { + return + } + r = io.NopCloser(bytes.NewReader(data)) } return } diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go index e089b9a..5499762 100644 --- a/internal/pkg/pkg_test.go +++ b/internal/pkg/pkg_test.go @@ -8,6 +8,7 @@ import ( "encoding/binary" "errors" "fmt" + "io" "io/fs" "net/http" "os" @@ -536,10 +537,14 @@ func TestCache(t *testing.T) { fs.ModeDir | 0500, )}, - {"loadData directory", overrideIdent{pkg.ID{0xff, 3}, stubArtifact{ + {"openFile directory", overrideIdent{pkg.ID{0xff, 3}, stubArtifact{ kind: pkg.KindTar, cure: func(c *pkg.CureContext) error { - _, err := c.LoadData(overrideChecksumFile{checksum: wantChecksum}) + r, err := c.OpenFile(overrideChecksumFile{checksum: wantChecksum}) + if err != nil { + panic(err) + } + _, err = io.ReadAll(r) return err }, }}, nil, pkg.Checksum{}, &os.PathError{ diff --git a/internal/pkg/tar.go b/internal/pkg/tar.go index 33f26f3..240a398 100644 --- a/internal/pkg/tar.go +++ b/internal/pkg/tar.go @@ -2,7 +2,6 @@ package pkg import ( "archive/tar" - "bytes" "compress/bzip2" "compress/gzip" "context" @@ -78,12 +77,17 @@ func (a *tarArtifact) Cure(c *CureContext) (err error) { var tr io.ReadCloser { - var data []byte - data, err = c.LoadData(a.f) - if err != nil { + + if tr, err = c.OpenFile(a.f); err != nil { return } - tr = io.NopCloser(bytes.NewReader(data)) + defer func(f io.ReadCloser) { + closeErr := f.Close() + if err == nil { + err = closeErr + } + }(tr) + tr = io.NopCloser(tr) } defer func() {