diff options
Diffstat (limited to 'internal/pkg/pkg.go')
| -rw-r--r-- | internal/pkg/pkg.go | 88 |
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]. |
