Cut metadata history over to shared model
This commit is contained in:
@@ -5,12 +5,12 @@ import "gitea.maximumdirect.net/eric/ConfigKit/internal/document"
|
||||
// Metadata provides detached effective presence/origin and chronological history
|
||||
// queries for a load. Its zero value contains no paths.
|
||||
type Metadata struct {
|
||||
effectivePaths map[string]Path
|
||||
fields map[string]FieldInfo
|
||||
history map[string][]Change
|
||||
inheritance []inheritanceOperation
|
||||
inheritanceIndex *inheritanceHistoryIndex
|
||||
historyModel *historyModel
|
||||
effectivePaths map[string]Path
|
||||
fields map[string]FieldInfo
|
||||
history map[string][]Change
|
||||
inheritance []inheritanceOperation
|
||||
historyBuilder *historyBuilder
|
||||
historyModel *historyModel
|
||||
}
|
||||
|
||||
// Lookup returns information for an effective path. Unknown and invalid paths
|
||||
@@ -50,15 +50,38 @@ func (m Metadata) effectiveField(path Path) (FieldInfo, bool) {
|
||||
// Removed historical paths can have history even though Lookup returns false.
|
||||
// Unknown and invalid paths return nil.
|
||||
func (m Metadata) History(path Path) []Change {
|
||||
if !m.hasHistoricalPath(path) {
|
||||
model := m.historyEvidence()
|
||||
if model == nil || !model.hasObservedShape(path) {
|
||||
return nil
|
||||
}
|
||||
history := m.history[path.String()]
|
||||
operations := m.inheritance
|
||||
if m.inheritanceIndex != nil {
|
||||
operations = m.inheritanceIndex.matchingOperations(path, m.inheritance)
|
||||
selections := model.selectHistory(path)
|
||||
if len(selections) == 0 {
|
||||
return nil
|
||||
}
|
||||
return historyWithInheritance(path, history, operations)
|
||||
changes := make([]Change, 0, len(selections))
|
||||
for _, selection := range selections {
|
||||
if !metadataHistoryRole(selection.role) || !selection.hasAttribution {
|
||||
continue
|
||||
}
|
||||
var previous []Origin
|
||||
if len(selection.previous) != 0 {
|
||||
previous = make([]Origin, len(selection.previous))
|
||||
for index, origin := range selection.previous {
|
||||
previous[index] = cloneOrigin(origin)
|
||||
}
|
||||
}
|
||||
changes = append(changes, Change{
|
||||
Path: selection.reportedPath.clone(),
|
||||
Origin: cloneOrigin(selection.attribution.origin),
|
||||
Previous: previous,
|
||||
Reasons: append([]string(nil), selection.attribution.reasons...),
|
||||
Dependencies: clonePaths(selection.attribution.dependencies),
|
||||
})
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
return nil
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
// HistoricalPaths returns the paths observed during loading, including effective
|
||||
@@ -73,7 +96,17 @@ func (m Metadata) History(path Path) []Change {
|
||||
// a path remains effective. Enumeration exposes no configuration values and does
|
||||
// not perform another load or resolve secrets.
|
||||
func (m Metadata) HistoricalPaths() []Path {
|
||||
return m.historyModel.historicalPaths()
|
||||
return m.historyEvidence().historicalPaths()
|
||||
}
|
||||
|
||||
func (m Metadata) historyEvidence() *historyModel {
|
||||
if m.historyModel != nil {
|
||||
return m.historyModel
|
||||
}
|
||||
if m.historyBuilder != nil {
|
||||
return m.historyBuilder.model
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Textual pointers are lookup keys, but explicit key/index kinds remain part of
|
||||
@@ -100,7 +133,7 @@ func matchesPathShape(query, candidate Path) bool {
|
||||
}
|
||||
|
||||
func (m Metadata) hasHistoricalPath(path Path) bool {
|
||||
return m.historyModel.hasObservedShape(path)
|
||||
return m.historyEvidence().hasObservedShape(path)
|
||||
}
|
||||
|
||||
func finalizeMetadataPaths(m *Metadata, final *document.Node, applications []historyApplication, earlier ...*document.Node) {
|
||||
@@ -109,7 +142,10 @@ func finalizeMetadataPaths(m *Metadata, final *document.Node, applications []his
|
||||
|
||||
func finalizeMetadataPathsWithResolution(m *Metadata, final *document.Node, applications []historyApplication, snapshots []resolutionSnapshot, earlier ...*document.Node) {
|
||||
finalizeEffectiveMetadataPaths(m, final)
|
||||
builder := newHistoryBuilder()
|
||||
builder := m.historyBuilder
|
||||
if builder == nil {
|
||||
builder = newHistoryBuilder()
|
||||
}
|
||||
if len(earlier) != 0 {
|
||||
builder.model.baseline = earlier[0]
|
||||
}
|
||||
@@ -164,12 +200,11 @@ func finalizeMetadataPathsWithResolution(m *Metadata, final *document.Node, appl
|
||||
builder.observeResolutionEvidence(snapshots)
|
||||
}
|
||||
m.historyModel = builder.freeze()
|
||||
m.inheritanceIndex = newInheritanceHistoryIndex(m.inheritance)
|
||||
m.historyBuilder = nil
|
||||
}
|
||||
|
||||
func finalizeEffectiveMetadataPaths(m *Metadata, final *document.Node) {
|
||||
m.effectivePaths = effectivePathIndex(final)
|
||||
m.inheritanceIndex = newInheritanceHistoryIndex(m.inheritance)
|
||||
}
|
||||
|
||||
// effectivePathIndex records document-derived paths with their contextual segment
|
||||
|
||||
Reference in New Issue
Block a user