package engine import ( "gitea.maximumdirect.net/eric/ConfigKit/internal/document" ) const historyNodeLimit = 4_000_000 type retainedNodeCounter struct { seen map[*document.Node]bool count int limit int } func newRetainedNodeCounter(limit int) *retainedNodeCounter { return &retainedNodeCounter{seen: make(map[*document.Node]bool), limit: limit} } func (c *retainedNodeCounter) add(root *document.Node) bool { if c == nil { return true } stack := []*document.Node{root} for len(stack) != 0 { node := stack[len(stack)-1] stack = stack[:len(stack)-1] if node == nil || c.seen[node] { continue } c.seen[node] = true c.count++ if c.limit >= 0 && c.count > c.limit { return false } for _, entry := range node.Mapping { stack = append(stack, entry.Value) } stack = append(stack, node.Sequence...) } return true } // History applications borrow immutable policy-validated input trees. Metadata // records answer presence and origin queries; replay reconstructs value changes. // Replay reconciles with canonical decoding before domain resolution so both // contracts agree on the effective result without retaining a tree per field. type historyApplication struct { layer Layer path Path value *document.Node origin Origin } func cloneHistoryApplications(values []historyApplication) []historyApplication { if values == nil { return nil } cloned := make([]historyApplication, len(values)) for index, value := range values { cloned[index] = historyApplication{ layer: value.layer, path: value.path.clone(), value: value.value, origin: cloneOrigin(value.origin), } } return cloned } func applicationOperationPath(application historyApplication, query Path, lookup *documentLookup) (Path, bool) { if !application.path.valid() || application.value == nil { return Path{}, false } if application.path.String() != "" { if pathsIntersect(application.path, query) { return application.path.clone(), true } return Path{}, false } if len(query.segments) == 0 { return Path{}, true } for length := 1; length <= len(query.segments); length++ { prefix := Path{segments: clonePathSegments(query.segments[:length], 0)} node, present := documentAtPathWithLookup(application.value, prefix, lookup) if !present { return Path{}, false } if length == len(query.segments) || node.Kind != document.Mapping { return prefix, true } } return Path{}, false } func historyApplicationOrigin(application historyApplication, operationPath Path, lookup *documentLookup) Origin { if application.origin.Layer != "" { return cloneOrigin(application.origin) } origin := Origin{Layer: application.layer} relative, ok := relativeHistoryPath(application.path, operationPath) if !ok { return origin } if node, present := documentAtPathWithLookup(application.value, relative, lookup); present { origin.Locations = []Location{publicLocation(node.Location)} } return origin } func relativeHistoryPath(root, path Path) (Path, bool) { if !pathContains(root, path) { return Path{}, false } return Path{segments: clonePathSegments(path.segments[len(root.segments):], 0)}, true } func pathsIntersect(left, right Path) bool { return pathContains(left, right) || pathContains(right, left) } func applyHistoryApplication(root **document.Node, application historyApplication, index *mappingIndex) { if application.path.String() == "" { mergeHistoryDocument(root, application.value, index) return } mergeHistoryAtPath(root, application.path, application.value, index) } func mergeHistoryDocument(target **document.Node, incoming *document.Node, index *mappingIndex) { if incoming == nil { return } if *target == nil || (*target).Kind != document.Mapping || incoming.Kind != document.Mapping { *target = document.Clone(incoming) return } for _, entry := range incoming.Mapping { position := index.find(*target, entry.Key) if position < 0 { cloned := entry cloned.Value = document.Clone(entry.Value) index.append(*target, cloned) continue } mergeHistoryDocument(&(*target).Mapping[position].Value, entry.Value, index) } } func mergeHistoryAtPath(root **document.Node, path Path, incoming *document.Node, index *mappingIndex) { if root == nil || *root == nil || len(path.segments) == 0 { mergeHistoryDocument(root, incoming, index) return } current := *root for segmentIndex, segment := range path.segments { if current.Kind != document.Mapping || segment.kind == pathSegmentIndex { return } position := index.find(current, segment.key) if segmentIndex == len(path.segments)-1 { if position < 0 { index.append(current, document.Entry{Key: segment.key, Value: document.Clone(incoming)}) } else { mergeHistoryDocument(¤t.Mapping[position].Value, incoming, index) } return } if position < 0 { child := &document.Node{Kind: document.Mapping} index.append(current, document.Entry{Key: segment.key, Value: child}) current = child } else { current = current.Mapping[position].Value } } } // Resolution records describe one before/final transformation, not assignment // order. A parent already carries its descendants' final values; merge overlapping // intent into that event rather than replay a child assignment a second time. func coalescedResolutionSnapshots(snapshots []resolutionSnapshot) []resolutionSnapshot { groups := make([]resolutionSnapshot, 0, len(snapshots)) reasons := make([]map[string]struct{}, 0, len(snapshots)) dependencies := make([]map[string]struct{}, 0, len(snapshots)) var coverage pathPrefixIndex for _, snapshot := range snapshots { pointer := snapshot.change.Path.String() groupIndex := -1 coverage.visitAncestors(pointer, func(id int) { if groupIndex < 0 || id < groupIndex { groupIndex = id } }) if groupIndex >= 0 { group := &groups[groupIndex] for _, reason := range snapshot.change.Reasons { if _, found := reasons[groupIndex][reason]; !found { reasons[groupIndex][reason] = struct{}{} group.change.Reasons = append(group.change.Reasons, reason) } } for _, dependency := range snapshot.change.Dependencies { dependencyPointer := dependency.String() if _, found := dependencies[groupIndex][dependencyPointer]; !found { dependencies[groupIndex][dependencyPointer] = struct{}{} group.change.Dependencies = append(group.change.Dependencies, dependency.clone()) } } if snapshot.change.Origin.Operation == ChangeNormalization { group.change.Origin.Operation = ChangeNormalization } continue } snapshot.change = cloneChange(snapshot.change) groups = append(groups, snapshot) reasonSet := make(map[string]struct{}, len(snapshot.change.Reasons)) for _, reason := range snapshot.change.Reasons { reasonSet[reason] = struct{}{} } reasons = append(reasons, reasonSet) dependencySet := make(map[string]struct{}, len(snapshot.change.Dependencies)) for _, dependency := range snapshot.change.Dependencies { dependencySet[dependency.String()] = struct{}{} } dependencies = append(dependencies, dependencySet) coverage.insert(pointer, len(groups)-1) } return groups } func replaceHistoryPath(root **document.Node, path Path, replacement *document.Node) { if root == nil || *root == nil { return } if len(path.segments) == 0 { *root = document.Clone(replacement) return } current := *root for index, segment := range path.segments { last := index == len(path.segments)-1 switch current.Kind { case document.Mapping: if segment.kind == pathSegmentIndex { return } position := documentEntryIndex(current.Mapping, segment.key) if position < 0 { if replacement == nil { return } child := &document.Node{Kind: document.Mapping} if last { child = document.Clone(replacement) } current.Mapping = append(current.Mapping, document.Entry{Key: segment.key, Value: child}) if last { return } current = child continue } if last { if replacement == nil { current.Mapping = append(current.Mapping[:position], current.Mapping[position+1:]...) } else { current.Mapping[position].Value = document.Clone(replacement) } return } current = current.Mapping[position].Value case document.Sequence: position, ok := schemaIndex(segment) if !ok || position >= len(current.Sequence) { return } if last { if replacement != nil { current.Sequence[position] = document.Clone(replacement) } return } current = current.Sequence[position] default: return } } } func historyNodesWithinLimit(baseline, input, final *document.Node, applications []historyApplication, resolutions []resolutionSnapshot, inherited ...*inheritanceScope) bool { return historyNodesWithin(historyNodeLimit, baseline, input, final, applications, resolutions, inherited...) } func historyNodesWithin(limit int, baseline, input, final *document.Node, applications []historyApplication, resolutions []resolutionSnapshot, inherited ...*inheritanceScope) bool { seen := make(map[*document.Node]bool) count := 0 var visit func(*document.Node) bool visit = func(node *document.Node) bool { if node == nil || seen[node] { return true } seen[node] = true count++ if count > limit { return false } for _, entry := range node.Mapping { if !visit(entry.Value) { return false } } for _, child := range node.Sequence { if !visit(child) { return false } } return true } if !visit(baseline) || !visit(input) || !visit(final) { return false } for _, application := range applications { if !visit(application.value) { return false } } for _, resolution := range resolutions { if !visit(resolution.before) || !visit(resolution.after) { return false } } for _, expansion := range inherited { if expansion == nil { continue } if !visit(expansion.root) { return false } for _, operation := range expansion.operations { if !visit(operation.parent) || !visit(operation.effective) { return false } } for _, replacement := range expansion.replacements { if !visit(replacement.before) || !visit(replacement.after) { return false } } } return true }