Index resolution coverage and document reads
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user