77 lines
2.8 KiB
Go
77 lines
2.8 KiB
Go
package index
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"maps"
|
|
|
|
"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
|
|
}
|
|
|
|
// heldOldSections is the count the last pass wrote (the accepted set it held): a module that keeps using a section was
|
|
// accepted with it, so it is counted, and a fresh manifest changes nothing in it. Nil when none is held yet or it cannot be
|
|
// read; a failed read is said, never taken as 0 (issue 1966 D4).
|
|
func (ix *Indexer) heldOldSections(ctx context.Context) judge.OldSectionCounts {
|
|
value, _, found, err := ix.OldSections.Get(ctx, OldSectionsKey)
|
|
if err == nil && found {
|
|
var c OldSectionsCount
|
|
if c, err = DecodeOldSections(value); err == nil {
|
|
return c.Counts
|
|
}
|
|
}
|
|
if err != nil {
|
|
ix.logf("judge: the count of the old sections cannot be read (%v), so the zero rule is not applied in this pass", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 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
|
|
})
|
|
}
|