internal/pkg: make checksum available to cure
All checks were successful
Test / Create distribution (push) Successful in 50s
Test / Sandbox (push) Successful in 2m54s
Test / ShareFS (push) Successful in 4m41s
Test / Sandbox (race detector) (push) Successful in 5m21s
Test / Hpkg (push) Successful in 5m37s
Test / Hakurei (push) Successful in 5m49s
Test / Hakurei (race detector) (push) Successful in 7m27s
Test / Flake checks (push) Successful in 1m43s
All checks were successful
Test / Create distribution (push) Successful in 50s
Test / Sandbox (push) Successful in 2m54s
Test / ShareFS (push) Successful in 4m41s
Test / Sandbox (race detector) (push) Successful in 5m21s
Test / Hpkg (push) Successful in 5m37s
Test / Hakurei (push) Successful in 5m49s
Test / Hakurei (race detector) (push) Successful in 7m27s
Test / Flake checks (push) Successful in 1m43s
This enables deduplication by value as implemented in execArtifact. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -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{}),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user