forked from rosa/hakurei
internal/pkg: implementation revisions
This enables changing the behaviour of an artifact implementation without changing its IR structure. Unfortunately this changes the IR header structure resulting in many rebuilds. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
+20
-3
@@ -278,10 +278,11 @@ func (ic *irCache) encode(
|
||||
return *a == *b
|
||||
})
|
||||
|
||||
// kind uint64 | deps_sz uint64
|
||||
var buf [wordSize * 2]byte
|
||||
// kind uint64 | rev uint64 | deps_sz uint64
|
||||
var buf [wordSize * 3]byte
|
||||
binary.LittleEndian.PutUint64(buf[:], uint64(a.Kind()))
|
||||
binary.LittleEndian.PutUint64(buf[wordSize:], uint64(len(idents)))
|
||||
binary.LittleEndian.PutUint64(buf[wordSize:], GetRevision(a))
|
||||
binary.LittleEndian.PutUint64(buf[wordSize*2:], uint64(len(idents)))
|
||||
if _, err = w.Write(buf[:]); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -740,6 +741,15 @@ func (ir *IRReader) ReadString() string {
|
||||
return unsafe.String(unsafe.SliceData(p), len(p))
|
||||
}
|
||||
|
||||
// A RevisionError describes the first [Artifact] in an IR stream claiming a
|
||||
// revision not supported by the registered implementation.
|
||||
type RevisionError [2]uint64
|
||||
|
||||
func (e RevisionError) Error() string {
|
||||
return "claimed revision " + strconv.FormatUint(e[0], 10) +
|
||||
" differs from implementation value " + strconv.FormatUint(e[1], 10)
|
||||
}
|
||||
|
||||
// decode decodes the next [Artifact] in the IR stream and returns any buffer
|
||||
// originating from [Cache] before returning. decode returns [io.EOF] if and
|
||||
// only if the underlying [io.Reader] is already read to EOF.
|
||||
@@ -772,6 +782,9 @@ func (d *IRDecoder) decode() (a Artifact, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
ir.mustRead(ir.buf[:])
|
||||
rev := binary.LittleEndian.Uint64(ir.buf[:])
|
||||
|
||||
defer ir.putAll()
|
||||
ir.mustRead(ir.buf[:])
|
||||
sz := binary.LittleEndian.Uint64(ir.buf[:])
|
||||
@@ -792,6 +805,10 @@ func (d *IRDecoder) decode() (a Artifact, err error) {
|
||||
err = syscall.ENOTRECOVERABLE
|
||||
return
|
||||
}
|
||||
if _rev := GetRevision(a); _rev != rev {
|
||||
err = RevisionError{rev, _rev}
|
||||
return
|
||||
}
|
||||
|
||||
if ir.count != -1 {
|
||||
err = ErrRemainingIR
|
||||
|
||||
Reference in New Issue
Block a user