internal/pkg: content-based dependency substitution
All checks were successful
Test / Create distribution (push) Successful in 1m4s
Test / Sandbox (push) Successful in 2m48s
Test / ShareFS (push) Successful in 3m42s
Test / Hakurei (push) Successful in 3m57s
Test / Sandbox (race detector) (push) Successful in 5m23s
Test / Hakurei (race detector) (push) Successful in 6m35s
Test / Flake checks (push) Successful in 1m21s
All checks were successful
Test / Create distribution (push) Successful in 1m4s
Test / Sandbox (push) Successful in 2m48s
Test / ShareFS (push) Successful in 3m42s
Test / Hakurei (push) Successful in 3m57s
Test / Sandbox (race detector) (push) Successful in 5m23s
Test / Hakurei (race detector) (push) Successful in 6m35s
Test / Flake checks (push) Successful in 1m21s
This change introduces a new fast path for FloodArtifact. It is taken when a curing artifact has identical-by-content controlled relevant inputs and are otherwise identical to an already-cured artifact. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -76,6 +76,9 @@ type IContext struct {
|
||||
// Written to by various methods, should be zeroed after [Artifact.Params]
|
||||
// returns and must not be exposed directly.
|
||||
w io.Writer
|
||||
// Optional identifier to checksum cache, replaces [IRKindIdent] with
|
||||
// checksum values if non-nil.
|
||||
ident map[unique.Handle[ID]]unique.Handle[Checksum]
|
||||
}
|
||||
|
||||
// irZero is a zero IR word.
|
||||
@@ -163,7 +166,15 @@ func (i *IContext) WriteIdent(a Artifact) {
|
||||
defer i.ic.putIdentBuf(buf)
|
||||
|
||||
IRKindIdent.encodeHeader(0).put(buf[:])
|
||||
*(*ID)(buf[wordSize:]) = i.ic.Ident(a).Value()
|
||||
if i.ident != nil {
|
||||
checksum, ok := i.ident[i.ic.Ident(a)]
|
||||
if !ok {
|
||||
panic(InvalidLookupError(checksum.Value()))
|
||||
}
|
||||
*(*ID)(buf[wordSize:]) = checksum.Value()
|
||||
} else {
|
||||
*(*ID)(buf[wordSize:]) = i.ic.Ident(a).Value()
|
||||
}
|
||||
i.mustWrite(buf[:])
|
||||
}
|
||||
|
||||
@@ -207,6 +218,16 @@ func (i *IContext) WriteString(s string) {
|
||||
// Encode writes a deterministic, efficient representation of a to w and returns
|
||||
// the first non-nil error encountered while writing to w.
|
||||
func (ic *irCache) Encode(w io.Writer, a Artifact) (err error) {
|
||||
return ic.encode(w, a, nil)
|
||||
}
|
||||
|
||||
// encode implements Encode but replaces identifiers with their cured checksums
|
||||
// for a non-nil ident. Caller must acquire Cache.identMu.
|
||||
func (ic *irCache) encode(
|
||||
w io.Writer,
|
||||
a Artifact,
|
||||
ident map[unique.Handle[ID]]unique.Handle[Checksum],
|
||||
) (err error) {
|
||||
deps := a.Dependencies()
|
||||
idents := make([]*extIdent, len(deps))
|
||||
for i, d := range deps {
|
||||
@@ -228,6 +249,17 @@ func (ic *irCache) Encode(w io.Writer, a Artifact) (err error) {
|
||||
return *a == *b
|
||||
})
|
||||
|
||||
// late substitution preserves order
|
||||
if ident != nil {
|
||||
for _, dbuf := range idents {
|
||||
checksum, ok := ident[unique.Make(ID(dbuf[wordSize:]))]
|
||||
if !ok {
|
||||
return InvalidLookupError(dbuf[wordSize:])
|
||||
}
|
||||
*(*ID)(dbuf[wordSize:]) = checksum.Value()
|
||||
}
|
||||
}
|
||||
|
||||
// kind uint64 | deps_sz uint64
|
||||
var buf [wordSize * 2]byte
|
||||
binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
|
||||
@@ -244,7 +276,7 @@ func (ic *irCache) Encode(w io.Writer, a Artifact) (err error) {
|
||||
}
|
||||
|
||||
func() {
|
||||
i := IContext{ic, w}
|
||||
i := IContext{ic, w, ident}
|
||||
|
||||
defer panicToError(&err)
|
||||
defer func() { i.ic, i.w = nil, nil }()
|
||||
|
||||
Reference in New Issue
Block a user