Index resolution coverage and document reads

This commit is contained in:
2026-10-09 03:32:30 +00:00
parent db2d8ed217
commit aa3b4a5881
5 changed files with 186 additions and 19 deletions

View File

@@ -272,14 +272,17 @@ func runResolution[T any](configuration *T, resolver func(*T, *Resolution) error
}
deltas := compareConfigurationValues(decoded.final, after)
ordered := orderedResolutionRecords(state.records)
coverage := newResolutionCoverageIndexFromRecords(ordered)
beforeLookup := buildDocumentLookup(decoded.final)
afterLookup := buildDocumentLookup(after)
for _, delta := range deltas {
if coveringResolutionRecord(ordered, delta.path) == nil {
if _, ok := coverage.deepestCoveringID(delta.path); !ok {
state.addDiagnostic(CodeResolveUnrecordedChange, delta.path, "application resolution changed a value without a covering record")
}
}
for _, record := range ordered {
_, beforePresent := documentAtPath(decoded.final, record.path)
afterNode, afterPresent := documentAtPath(after, record.path)
_, beforePresent := documentAtPathWithLookup(decoded.final, record.path, beforeLookup)
afterNode, afterPresent := documentAtPathWithLookup(after, record.path, afterLookup)
if !beforePresent && !afterPresent {
state.addDiagnostic(CodeResolveInvalidRecord, record.path, "resolution record does not identify an existing or removed value")
continue
@@ -294,8 +297,8 @@ func runResolution[T any](configuration *T, resolver func(*T, *Resolution) error
snapshots := make([]resolutionSnapshot, 0, len(ordered))
for _, record := range ordered {
beforeNode, _ := documentAtPath(decoded.final, record.path)
afterNode, _ := documentAtPath(after, record.path)
beforeNode, _ := documentAtPathWithLookup(decoded.final, record.path, beforeLookup)
afterNode, _ := documentAtPathWithLookup(after, record.path, afterLookup)
snapshots = append(snapshots, resolutionSnapshot{
change: Change{
Path: record.path.clone(),
@@ -331,14 +334,45 @@ func orderedResolutionRecords(records map[string]*resolutionRecord) []*resolutio
return result
}
func coveringResolutionRecord(records []*resolutionRecord, path Path) *resolutionRecord {
var covering *resolutionRecord
for _, record := range records {
if pathContains(record.path, path) && (covering == nil || len(record.path.segments) > len(covering.path.segments)) {
covering = record
type resolutionCoverageIndex struct {
prefix pathPrefixIndex
depths []int
}
func newResolutionCoverageIndex(paths []Path) *resolutionCoverageIndex {
index := &resolutionCoverageIndex{depths: make([]int, len(paths))}
for id, path := range paths {
index.depths[id] = len(path.segments)
if path.valid() {
index.prefix.insert(path.String(), id)
}
}
return covering
return index
}
func newResolutionCoverageIndexFromRecords(records []*resolutionRecord) *resolutionCoverageIndex {
index := &resolutionCoverageIndex{depths: make([]int, len(records))}
for id, record := range records {
index.depths[id] = len(record.path.segments)
if record.path.valid() {
index.prefix.insert(record.path.String(), id)
}
}
return index
}
func (index *resolutionCoverageIndex) deepestCoveringID(path Path) (int, bool) {
if !path.valid() {
return 0, false
}
bestID, bestDepth, found := 0, -1, false
index.prefix.visitAncestors(path.String(), func(id int) {
depth := index.depths[id]
if !found || depth > bestDepth || (depth == bestDepth && id < bestID) {
bestID, bestDepth, found = id, depth, true
}
})
return bestID, found
}
func pathContains(container, descendant Path) bool {