79 lines
2.9 KiB
Go
79 lines
2.9 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"maps"
|
|
"slices"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
|
|
"mesh-delivery-indexer/judge"
|
|
)
|
|
|
|
// How many accepted modules use each old section (issue 1966 D4; novox/hq ADR 0595 §11): the indexer counts them, the
|
|
// foundation left out, as it judges, keeps the count in its state oldsections under one key, and the tool
|
|
// indexer_old_sections reads it. The judge refuses a manifest of another module that uses a section whose count is 0.
|
|
const (
|
|
// OldSectionsTool is the tool that reads the count.
|
|
OldSectionsTool = "indexer_old_sections"
|
|
// OldSectionsState is the indexer's state of the count: the bucket mesh-delivery-indexer_oldsections.
|
|
OldSectionsState = "oldsections"
|
|
OldSectionsBucket = delivery.IndexerModule + "_" + OldSectionsState
|
|
// OldSectionsKey is the one key it holds.
|
|
OldSectionsKey = "counts"
|
|
)
|
|
|
|
// OldSectionsCount is the value of the oldsections state: per old section, the accepted modules outside the foundation using it.
|
|
type OldSectionsCount struct {
|
|
V int `json:"v"`
|
|
Counts map[string]int `json:"counts"`
|
|
}
|
|
|
|
// DecodeOldSections reads the oldsections value.
|
|
func DecodeOldSections(value []byte) (OldSectionsCount, error) {
|
|
var c OldSectionsCount
|
|
if err := json.Unmarshal(value, &c); err != nil {
|
|
return c, fmt.Errorf("the count of the old sections cannot be read: %w", err)
|
|
}
|
|
if c.V != 1 {
|
|
return c, fmt.Errorf("a count of the old sections of version %d, not 1", c.V)
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// countBefore counts the accepted modules using each old section as the pass starts: those whose verdict held says accepted,
|
|
// or which have none and are not fresh (acceptedBefore). A manifest is read leniently, since a module the judge now finds
|
|
// a problem in is still accepted (ADR 0579 §1) and still counts.
|
|
func (ix *Indexer) countBefore(ctx context.Context, raws map[string][]byte, digests map[string]string, fresh map[string]bool) judge.OldSectionCounts {
|
|
var accepted []catalogue.Manifest
|
|
for _, name := range slices.Sorted(maps.Keys(raws)) {
|
|
if !ix.acceptedBefore(ctx, digests[name], fresh) {
|
|
continue
|
|
}
|
|
if m, err := catalogue.Decode(raws[name]); err == nil {
|
|
m.Module = name
|
|
accepted = append(accepted, m)
|
|
}
|
|
}
|
|
return judge.CountOldSections(accepted)
|
|
}
|
|
|
|
// keepOldSections writes the counts under OldSectionsKey when they differ from the ones held.
|
|
func (ix *Indexer) keepOldSections(ctx context.Context, counts judge.OldSectionCounts) error {
|
|
if ix.OldSections == nil {
|
|
return nil
|
|
}
|
|
return write(ctx, ix.OldSections, OldSectionsKey, func(value []byte, found bool) ([]byte, bool, error) {
|
|
if found {
|
|
if cur, err := DecodeOldSections(value); err == nil && maps.Equal(cur.Counts, counts) {
|
|
return nil, false, nil
|
|
}
|
|
}
|
|
next, err := json.Marshal(OldSectionsCount{V: 1, Counts: counts})
|
|
return next, false, err
|
|
})
|
|
}
|