aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/pkg.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-06-04 18:12:03 +0900
committerOphestra <cat@gensokyo.uk>2026-06-04 18:33:04 +0900
commit76c1fb84c87ba12a22b64f7c471a92603365837f (patch)
treede04c0a8a45a636ebe78fd06b3097e5b8493e9cc /internal/pkg/pkg.go
parent729be19af39fb73e827bdb2798ac23942f9cf9e5 (diff)
internal/pkg: stream decompress artifact
The tarArtifact predates FileArtifact pipelining. This migrates decompression and buffering into a standalone artifact implementation. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/pkg/pkg.go')
-rw-r--r--internal/pkg/pkg.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 8b022d1f..09d91f73 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -508,6 +508,8 @@ const (
KindExecNet
// KindFile is the kind of [Artifact] returned by [NewFile].
KindFile
+ // KindDecompress is the kind of [Artifact] returned by [NewDecompress].
+ KindDecompress
// _kindEnd is the total number of kinds and does not denote a kind.
_kindEnd
@@ -795,6 +797,38 @@ func (c *Cache) getReader(r io.Reader) *bufio.Reader {
// putReader adds br to brPool.
func (c *Cache) putReader(br *bufio.Reader) { c.brPool.Put(br) }
+// bufioReadCloser is the concrete type of value returned by Cache.getReaderRC.
+type bufioReadCloser struct {
+ // Saved close error.
+ closeErr error
+ // Synchronises calls to Close.
+ closeOnce sync.Once
+
+ // For backing freelist.
+ c *Cache
+ // Underlying reader.
+ r io.ReadCloser
+ // Allocated from c.
+ *bufio.Reader
+}
+
+// Close closes the underlying reader, saves its return value, and returns the
+// [bufio.Reader] instance to the backing [Cache].
+func (brc *bufioReadCloser) Close() error {
+ brc.closeOnce.Do(func() {
+ br := brc.Reader
+ brc.Reader = nil
+ brc.c.putReader(br)
+ brc.closeErr = brc.r.Close()
+ })
+ return brc.closeErr
+}
+
+// getReaderRC is like getReader, but returns an [io.ReadCloser].
+func (c *Cache) getReaderRC(r io.ReadCloser) io.ReadCloser {
+ return &bufioReadCloser{c: c, r: r, Reader: c.getReader(r)}
+}
+
// getWriter is like [bufio.NewWriter] but for bwPool.
func (c *Cache) getWriter(w io.Writer) *bufio.Writer {
bw := c.bwPool.Get().(*bufio.Writer)