aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/pkg.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/pkg.go')
-rw-r--r--internal/pkg/pkg.go88
1 files changed, 14 insertions, 74 deletions
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 76bae916..154e20b0 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -65,35 +65,6 @@ func MustDecode(s string) (checksum Checksum) {
return
}
-// IContext is passed to [Artifact.Params] and provides identifier information
-// and the target [hash.Hash] for writing params into.
-//
-// Methods of IContext are safe for concurrent use. IContext is valid
-// until [Artifact.Params] returns.
-type IContext struct {
- // Address of underlying [Cache], should be zeroed or made unusable after
- // [Artifact.Params] returns and must not be exposed directly.
- cache *Cache
- // Made available for writing, should be zeroed after [Artifact.Params]
- // returns. Internal state must not be inspected.
- h hash.Hash
-}
-
-// Unwrap returns the underlying [context.Context].
-func (i *IContext) Unwrap() context.Context { return i.cache.ctx }
-
-// GetHash returns the underlying [hash.Hash] for writing. Callers must not
-// attempt to inspect its internal state.
-func (i *IContext) GetHash() hash.Hash { return i.h }
-
-// WriteIdent writes the identifier of [Artifact] to the underlying [hash.Hash].
-func (i *IContext) WriteIdent(a Artifact) {
- buf := i.cache.getIdentBuf()
- *(*ID)(buf[wordSize:]) = i.cache.Ident(a).Value()
- i.h.Write(buf[wordSize:])
- i.cache.putIdentBuf(buf)
-}
-
// TContext is passed to [TrivialArtifact.Cure] and provides information and
// methods required for curing the [TrivialArtifact].
//
@@ -238,10 +209,12 @@ type Artifact interface {
// [Artifact] is allowed to return the same [Kind] value.
Kind() Kind
- // Params writes opaque bytes that describes [Artifact]. Implementations
+ // Params writes deterministic values describing [Artifact]. Implementations
// must guarantee that these values are unique among differing instances
- // of the same implementation with the same dependencies. Callers must not
- // attempt to interpret these params.
+ // of the same implementation with identical dependencies and conveys enough
+ // information to create another instance of [Artifact] identical to the
+ // instance emitting these values. The new instance created via [IRReadFunc]
+ // from these values must then produce identical IR values.
//
// Result must remain identical across multiple invocations.
Params(ctx *IContext)
@@ -564,47 +537,13 @@ func (c *Cache) unsafeIdent(a Artifact, encodeKind bool) (
return
}
- deps := a.Dependencies()
- idents := make([]*extIdent, len(deps))
- for i, d := range deps {
- dbuf, did := c.unsafeIdent(d, true)
- if dbuf == nil {
- dbuf = c.getIdentBuf()
- binary.LittleEndian.PutUint64(dbuf[:], uint64(d.Kind()))
- *(*ID)(dbuf[wordSize:]) = did.Value()
- } else {
- c.storeIdent(d, dbuf)
- }
- defer c.putIdentBuf(dbuf)
- idents[i] = dbuf
- }
- slices.SortFunc(idents, func(a, b *extIdent) int {
- return bytes.Compare(a[:], b[:])
- })
- idents = slices.CompactFunc(idents, func(a, b *extIdent) bool {
- return *a == *b
- })
-
buf = c.getIdentBuf()
h := sha512.New384()
- binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
- h.Write(buf[:wordSize])
- for _, dn := range idents {
- h.Write(dn[:])
- }
- kcBuf := c.getIdentBuf()
- if kc, ok := a.(KnownChecksum); ok {
- *(*Checksum)(kcBuf[:]) = kc.Checksum()
- } else {
- *(*Checksum)(kcBuf[:]) = Checksum{}
+ if err := c.Encode(h, a); err != nil {
+ // unreachable
+ panic(err)
}
- h.Write((*Checksum)(kcBuf[:])[:])
- c.putIdentBuf(kcBuf)
-
- i := IContext{c, h}
- a.Params(&i)
- i.cache, i.h = nil, nil
-
+ binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
h.Sum(buf[wordSize:wordSize])
return
}
@@ -1000,8 +939,9 @@ func (c *Cache) openFile(f FileArtifact) (r io.ReadCloser, err error) {
return
}
-// InvalidFileModeError describes an [Artifact.Cure] that did not result in
-// a regular file or directory located at the work pathname.
+// InvalidFileModeError describes a [FloodArtifact.Cure] or
+// [TrivialArtifact.Cure] that did not result in a regular file or directory
+// located at the work pathname.
type InvalidFileModeError fs.FileMode
// Error returns a constant string.
@@ -1009,8 +949,8 @@ func (e InvalidFileModeError) Error() string {
return "artifact did not produce a regular file or directory"
}
-// NoOutputError describes an [Artifact.Cure] that did not populate its
-// work pathname despite completing successfully.
+// NoOutputError describes a [FloodArtifact.Cure] or [TrivialArtifact.Cure]
+// that did not populate its work pathname despite completing successfully.
type NoOutputError struct{}
// Unwrap returns [os.ErrNotExist].