aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-03-07 01:38:11 +0900
committerOphestra <cat@gensokyo.uk>2026-03-07 02:18:00 +0900
commitba5d882ef281450efe10aea60b05976cb533ab92 (patch)
treef10b6abea4bc07b86ef23789e3dcf65545fd1bcc
parent1e0d68a29e824b25c556d28b6a0cd0c3ab39ffef (diff)
internal/rosa: stream format for cure report
This is for efficient cure status retrieval by the package website server. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/rosa/report.go238
-rw-r--r--internal/rosa/report_test.go57
2 files changed, 295 insertions, 0 deletions
diff --git a/internal/rosa/report.go b/internal/rosa/report.go
new file mode 100644
index 00000000..c0022279
--- /dev/null
+++ b/internal/rosa/report.go
@@ -0,0 +1,238 @@
+package rosa
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "runtime/debug"
+ "strconv"
+ "sync"
+ "syscall"
+ "unique"
+ "unsafe"
+
+ "hakurei.app/internal/pkg"
+ "hakurei.app/message"
+)
+
+// wordSize is the boundary which binary segments are always aligned to.
+const wordSize = 8
+
+// padSize returns the padding size for aligning sz.
+func padSize[T int | int64](sz T) T {
+ return (wordSize - (sz)%wordSize) % wordSize
+}
+
+// WriteReport writes a report of all available [PArtifact] to w.
+func WriteReport(msg message.Msg, w io.Writer, c *pkg.Cache) error {
+ var (
+ zero [wordSize]byte
+ buf [len(pkg.ID{}) + wordSize]byte
+ )
+ for i := range PresetEnd {
+ a := Std.Load(PArtifact(i))
+ if _, ok := a.(pkg.FileArtifact); ok {
+ msg.Verbosef("skipping file artifact %s", artifactsM[i].Name)
+ continue
+ }
+
+ id := c.Ident(a)
+
+ var f *os.File
+ if r, err := c.OpenStatus(a); err != nil {
+ if errors.Is(err, os.ErrNotExist) {
+ msg.Verbosef("artifact %s unavailable", artifactsM[i].Name)
+ continue
+ }
+ return err
+ } else {
+ f = r.(*os.File)
+ }
+
+ msg.Verbosef("writing artifact %s...", artifactsM[i].Name)
+
+ var sz int64
+ if fi, err := f.Stat(); err != nil {
+ _ = f.Close()
+ return err
+ } else {
+ sz = fi.Size()
+ }
+
+ *(*pkg.ID)(buf[:]) = id.Value()
+ binary.LittleEndian.PutUint64(buf[len(pkg.ID{}):], uint64(sz))
+ if _, err := w.Write(buf[:]); err != nil {
+ _ = f.Close()
+ return err
+ }
+
+ if n, err := io.Copy(w, f); err != nil {
+ _ = f.Close()
+ return err
+ } else if n != sz {
+ _ = f.Close()
+ return fmt.Errorf("strange status file copy: %d != %d", n, sz)
+ } else if err = f.Close(); err != nil {
+ return err
+ }
+
+ if psz := padSize(sz); psz > 0 {
+ if _, err := w.Write(zero[:psz]); err != nil {
+ return err
+ }
+ }
+
+ // existence of status implies cured artifact
+ var n int
+ if pathname, _, err := c.Cure(a); err != nil {
+ return err
+ } else if n, err = pkg.Flatten(
+ os.DirFS(pathname.String()), ".",
+ io.Discard,
+ ); err != nil {
+ return err
+ }
+ binary.LittleEndian.PutUint64(buf[:], uint64(n))
+ if _, err := w.Write(buf[:wordSize]); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// Report provides efficient access to a report file populated by [WriteReport].
+type Report struct {
+ // Underlying file, must not be exposed directly.
+ f *os.File
+ // Slice backed by f. Access must be prepared by HandleAccess.
+ data []byte
+
+ // Offsets into data for each identifier.
+ offsets map[unique.Handle[pkg.ID]]int
+
+ // Outcome of a call to Close.
+ closeErr error
+ // Synchronises calls to Close.
+ closeOnce sync.Once
+}
+
+// OpenReport opens a file populated by [WriteReport]
+func OpenReport(pathname string) (rp *Report, err error) {
+ var r Report
+ if r.f, err = os.Open(pathname); err != nil {
+ return
+ }
+ defer func() {
+ if err != nil {
+ _ = r.f.Close()
+ if r.data != nil {
+ _ = syscall.Munmap(r.data)
+ }
+ }
+ }()
+
+ var fi os.FileInfo
+ if fi, err = r.f.Stat(); err != nil {
+ return
+ }
+
+ if r.data, err = syscall.Mmap(
+ int(r.f.Fd()),
+ 0,
+ int(fi.Size()),
+ syscall.PROT_READ,
+ syscall.MAP_PRIVATE,
+ ); err != nil {
+ return
+ }
+
+ defer r.HandleAccess(&err)()
+
+ var offset int
+ r.offsets = make(map[unique.Handle[pkg.ID]]int)
+ for offset < len(r.data) {
+ id := unique.Make((pkg.ID)(r.data[offset:]))
+ offset += len(pkg.ID{})
+ r.offsets[id] = offset
+ offset += int(binary.LittleEndian.Uint64(r.data[offset:])) + wordSize
+ offset += padSize(offset)
+ offset += wordSize
+ }
+ return &r, nil
+}
+
+// ReportIOError describes an I/O error while accessing a [Report].
+type ReportIOError struct {
+ Offset int
+ Err error
+}
+
+// Unwrap returns the underlying runtime error.
+func (e *ReportIOError) Unwrap() error { return e.Err }
+
+// Error returns a description of the error offset.
+func (e *ReportIOError) Error() string {
+ return "report I/O error at offset " + strconv.Itoa(e.Offset)
+}
+
+// HandleAccess prepares for accessing memory returned by a method of [Report]
+// and returns a function that must be deferred by the caller.
+func (r *Report) HandleAccess(errP *error) func() {
+ pof := debug.SetPanicOnFault(true)
+ return func() {
+ debug.SetPanicOnFault(pof)
+
+ v := recover()
+ if v == nil {
+ return
+ }
+
+ if err, ok := v.(error); !ok {
+ panic(v)
+ } else if *errP != nil {
+ return
+ } else {
+ *errP = err
+ }
+
+ var runtimeError interface {
+ Addr() uintptr
+ runtime.Error
+ }
+ if errors.As(*errP, &runtimeError) {
+ offset := int(runtimeError.Addr() - uintptr(unsafe.Pointer(unsafe.SliceData(r.data))))
+ // best effort for fragile uintptr
+ if offset >= 0 {
+ *errP = &ReportIOError{offset, *errP}
+ }
+ }
+ }
+}
+
+// ArtifactOf returns information of a [pkg.Artifact] corresponding to id.
+func (r *Report) ArtifactOf(id unique.Handle[pkg.ID]) (status []byte, n int64) {
+ if offset, ok := r.offsets[id]; !ok {
+ n = -1
+ } else {
+ sz := int(binary.LittleEndian.Uint64(r.data[offset:]))
+ offset += wordSize
+
+ status = r.data[offset : offset+sz]
+ offset += sz + padSize(sz)
+
+ n = int64(binary.LittleEndian.Uint64(r.data[offset:]))
+ }
+ return
+}
+
+// Close closes the underlying file and releases all associated resources.
+func (r *Report) Close() error {
+ r.closeOnce.Do(func() {
+ err := syscall.Munmap(r.data)
+ r.closeErr = errors.Join(err, r.f.Close())
+ })
+ return r.closeErr
+}
diff --git a/internal/rosa/report_test.go b/internal/rosa/report_test.go
new file mode 100644
index 00000000..ca29cf36
--- /dev/null
+++ b/internal/rosa/report_test.go
@@ -0,0 +1,57 @@
+package rosa_test
+
+import (
+ "errors"
+ "os"
+ "path"
+ "syscall"
+ "testing"
+ "unique"
+
+ "hakurei.app/internal/pkg"
+ "hakurei.app/internal/rosa"
+)
+
+func TestReportZeroLength(t *testing.T) {
+ report := path.Join(t.TempDir(), "report")
+ if err := os.WriteFile(report, nil, 0400); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := rosa.OpenReport(report); !errors.Is(err, syscall.EINVAL) {
+ t.Fatalf("OpenReport: error = %v", err)
+ }
+}
+
+func TestReportSIGSEGV(t *testing.T) {
+ report := path.Join(t.TempDir(), "report")
+ if err := os.WriteFile(report, make([]byte, 64), 0400); err != nil {
+ t.Fatal(err)
+ }
+
+ if r, err := rosa.OpenReport(report); err != nil {
+ t.Fatalf("OpenReport: error = %v", err)
+ } else {
+ status, n := r.ArtifactOf(unique.Make(pkg.ID{}))
+ if len(status) != 0 {
+ t.Errorf("ArtifactsOf: status = %#v", status)
+ }
+ if n != 0 {
+ t.Errorf("ArtifactsOf: n = %d", n)
+ }
+
+ if err = r.Close(); err != nil {
+ t.Fatalf("Close: error = %v", err)
+ }
+
+ defer func() {
+ ioErr := err.(*rosa.ReportIOError)
+ if ioErr.Offset != 48 {
+ panic(ioErr)
+ }
+ }()
+ defer r.HandleAccess(&err)()
+ r.ArtifactOf(unique.Make(pkg.ID{}))
+ }
+
+}