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.go94
1 files changed, 54 insertions, 40 deletions
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 65bf5e17..738eb5c0 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -187,7 +187,7 @@ type FContext struct {
TContext
// Cured top-level dependencies looked up by Pathname.
- deps map[Artifact]*check.Absolute
+ deps map[Artifact]cureRes
}
// InvalidLookupError is the identifier of non-dependency [Artifact] looked up
@@ -200,15 +200,17 @@ func (e InvalidLookupError) Error() string {
var _ error = InvalidLookupError{}
-// Pathname returns the identifier pathname of an [Artifact]. Calling Pathname
-// with an [Artifact] not part of the slice returned by [Artifact.Dependencies]
-// panics.
-func (f *FContext) Pathname(a Artifact) *check.Absolute {
- if p, ok := f.deps[a]; ok {
- return p
- } else {
- panic(InvalidLookupError(f.cache.Ident(a).Value()))
+// GetArtifact returns the identifier pathname and checksum of an [Artifact].
+// Calling Pathname with an [Artifact] not part of the slice returned by
+// [Artifact.Dependencies] panics.
+func (f *FContext) GetArtifact(a Artifact) (
+ pathname *check.Absolute,
+ checksum unique.Handle[Checksum],
+) {
+ if res, ok := f.deps[a]; ok {
+ return res.pathname, res.checksum
}
+ panic(InvalidLookupError(f.cache.Ident(a).Value()))
}
// An Artifact is a read-only reference to a piece of data that may be created
@@ -378,6 +380,12 @@ const (
checksumLinknamePrefix = "../" + dirChecksum + "/"
)
+// cureRes are the non-error results returned by [Cache.Cure].
+type cureRes struct {
+ pathname *check.Absolute
+ checksum unique.Handle[Checksum]
+}
+
// A pendingArtifactDep is a dependency [Artifact] pending concurrent curing,
// subject to the cures limit. Values pointed to by result addresses are safe
// to access after the [sync.WaitGroup] associated with this pendingArtifactDep
@@ -389,7 +397,7 @@ type pendingArtifactDep struct {
// Address of result pathname populated during [Cache.Cure] and dereferenced
// if curing succeeds.
- resP **check.Absolute
+ resP *cureRes
// Address of result error slice populated during [Cache.Cure], dereferenced
// after acquiring errsMu if curing fails. No additional action is taken,
@@ -437,7 +445,7 @@ type Cache struct {
checksumMu sync.RWMutex
// Identifier to content pair cache.
- ident map[unique.Handle[ID]]Checksum
+ ident map[unique.Handle[ID]]unique.Handle[Checksum]
// Identifier to error pair for unrecoverably faulted [Artifact].
identErr map[unique.Handle[ID]]error
// Pending identifiers, accessed through Cure for entries not in ident.
@@ -650,7 +658,7 @@ func (c *Cache) Scrub(checks int) error {
c.checksumMu.Lock()
defer c.checksumMu.Unlock()
- c.ident = make(map[unique.Handle[ID]]Checksum)
+ c.ident = make(map[unique.Handle[ID]]unique.Handle[Checksum])
c.identErr = make(map[unique.Handle[ID]]error)
c.artifact.Clear()
@@ -848,7 +856,7 @@ func (c *Cache) Scrub(checks int) error {
// identifier is stored in identPending and a non-nil channel is returned.
func (c *Cache) loadOrStoreIdent(id unique.Handle[ID]) (
done chan<- struct{},
- checksum Checksum,
+ checksum unique.Handle[Checksum],
err error,
) {
var ok bool
@@ -887,14 +895,14 @@ func (c *Cache) loadOrStoreIdent(id unique.Handle[ID]) (
func (c *Cache) finaliseIdent(
done chan<- struct{},
id unique.Handle[ID],
- checksum *Checksum,
+ checksum unique.Handle[Checksum],
err error,
) {
c.identMu.Lock()
if err != nil {
c.identErr[id] = err
} else {
- c.ident[id] = *checksum
+ c.ident[id] = checksum
}
delete(c.identPending, id)
c.identMu.Unlock()
@@ -1091,7 +1099,7 @@ func (e DependencyError) Error() string {
// calls to Cure are not subject to the cures limit.
func (c *Cache) Cure(a Artifact) (
pathname *check.Absolute,
- checksum Checksum,
+ checksum unique.Handle[Checksum],
err error,
) {
if c.threshold > 0 {
@@ -1181,7 +1189,7 @@ func (e *DependencyCureError) Error() string {
// cure implements Cure without checking the full dependency graph.
func (c *Cache) cure(a Artifact) (
pathname *check.Absolute,
- checksum Checksum,
+ checksum unique.Handle[Checksum],
err error,
) {
id := c.Ident(a)
@@ -1193,7 +1201,7 @@ func (c *Cache) cure(a Artifact) (
defer func() {
if err != nil {
pathname = nil
- checksum = Checksum{}
+ checksum = unique.Handle[Checksum]{}
}
}()
@@ -1202,7 +1210,7 @@ func (c *Cache) cure(a Artifact) (
if done == nil {
return
} else {
- defer func() { c.finaliseIdent(done, id, &checksum, err) }()
+ defer func() { c.finaliseIdent(done, id, checksum, err) }()
}
_, err = os.Lstat(pathname.String())
@@ -1211,7 +1219,12 @@ func (c *Cache) cure(a Artifact) (
if name, err = os.Readlink(pathname.String()); err != nil {
return
}
- err = Decode(&checksum, path.Base(name))
+ buf := c.getIdentBuf()
+ err = Decode((*Checksum)(buf[:]), path.Base(name))
+ if err == nil {
+ checksum = unique.Make(Checksum(buf[:]))
+ }
+ c.putIdentBuf(buf)
return
}
if !errors.Is(err, os.ErrNotExist) {
@@ -1234,8 +1247,8 @@ func (c *Cache) cure(a Artifact) (
var checksumPathname *check.Absolute
var checksumFi os.FileInfo
if kc, ok := a.(KnownChecksum); ok {
- checksum = kc.Checksum()
- checksums = Encode(checksum)
+ checksum = unique.Make(kc.Checksum())
+ checksums = Encode(checksum.Value())
checksumPathname = c.base.Append(
dirChecksum,
checksums,
@@ -1288,8 +1301,11 @@ func (c *Cache) cure(a Artifact) (
if checksumPathname == nil {
h := sha512.New384()
h.Write(data)
- h.Sum(checksum[:0])
- checksums = Encode(checksum)
+ buf := c.getIdentBuf()
+ h.Sum(buf[:0])
+ checksum = unique.Make(Checksum(buf[:]))
+ checksums = Encode(Checksum(buf[:]))
+ c.putIdentBuf(buf)
checksumPathname = c.base.Append(
dirChecksum,
checksums,
@@ -1297,10 +1313,10 @@ func (c *Cache) cure(a Artifact) (
} else if c.IsStrict() {
h := sha512.New384()
h.Write(data)
- if got := Checksum(h.Sum(nil)); got != checksum {
+ if got := Checksum(h.Sum(nil)); got != checksum.Value() {
err = &ChecksumMismatchError{
Got: got,
- Want: checksum,
+ Want: checksum.Value(),
}
return
}
@@ -1355,11 +1371,11 @@ func (c *Cache) cure(a Artifact) (
case FloodArtifact:
deps := a.Dependencies()
- f := FContext{t, make(map[Artifact]*check.Absolute, len(deps))}
+ f := FContext{t, make(map[Artifact]cureRes, len(deps))}
var wg sync.WaitGroup
wg.Add(len(deps))
- res := make([]*check.Absolute, len(deps))
+ res := make([]cureRes, len(deps))
errs := make(DependencyCureError, 0, len(deps))
var errsMu sync.Mutex
for i, d := range deps {
@@ -1422,20 +1438,18 @@ func (c *Cache) cure(a Artifact) (
}
if checksumPathname == nil {
- checksum = gotChecksum
- checksums = Encode(checksum)
+ checksum = unique.Make(gotChecksum)
+ checksums = Encode(gotChecksum)
checksumPathname = c.base.Append(
dirChecksum,
checksums,
)
- } else {
- if gotChecksum != checksum {
- err = &ChecksumMismatchError{
- Got: gotChecksum,
- Want: checksum,
- }
- return
+ } else if gotChecksum != checksum.Value() {
+ err = &ChecksumMismatchError{
+ Got: gotChecksum,
+ Want: checksum.Value(),
}
+ return
}
if err = os.Chmod(t.work.String(), 0700); err != nil {
@@ -1470,9 +1484,9 @@ func (c *Cache) cure(a Artifact) (
func (pending *pendingArtifactDep) cure(c *Cache) {
defer pending.Done()
- pathname, _, err := c.cure(pending.a)
+ var err error
+ pending.resP.pathname, pending.resP.checksum, err = c.cure(pending.a)
if err == nil {
- *pending.resP = pathname
return
}
@@ -1536,7 +1550,7 @@ func open(
msg: msg,
base: base,
- ident: make(map[unique.Handle[ID]]Checksum),
+ ident: make(map[unique.Handle[ID]]unique.Handle[Checksum]),
identErr: make(map[unique.Handle[ID]]error),
identPending: make(map[unique.Handle[ID]]<-chan struct{}),
}