Index stable history trees during normalization
This commit is contained in:
@@ -26,7 +26,6 @@ type historySourcePayload struct {
|
||||
hasApplicationRef bool
|
||||
path Path
|
||||
origin Origin
|
||||
contributions []historyPayloadRef
|
||||
}
|
||||
|
||||
func (builder *historyBuilder) observeBaseline(root *document.Node) {
|
||||
@@ -128,8 +127,7 @@ func (builder *historyBuilder) observeSourceEvidence(root *document.Node, origin
|
||||
if !found || origin.Layer == "" || sourceOriginRepresentedByOperation(builder.model, path, origin) {
|
||||
return
|
||||
}
|
||||
contributions := builder.sourceContributions(path, origin)
|
||||
payload := builder.addSourceSummary(path, origin, contributions)
|
||||
payload := builder.addSourceSummary(path, origin)
|
||||
attribution := builder.addAttribution(origin, nil, nil)
|
||||
builder.addObservation(historyObservation{
|
||||
path: path, phase: historyPhaseSources, payload: payload,
|
||||
@@ -173,69 +171,17 @@ func (builder *historyBuilder) addSourcePayload(application *historyApplication,
|
||||
return payload
|
||||
}
|
||||
|
||||
func (builder *historyBuilder) addSourceSummary(path Path, origin Origin, contributions []historyPayloadRef) historyPayloadRef {
|
||||
func (builder *historyBuilder) addSourceSummary(path Path, origin Origin) historyPayloadRef {
|
||||
payload := builder.nextPayload(historyPhaseSources)
|
||||
if payload.id != len(builder.model.sourcePayloads) {
|
||||
panic("configkit: source payload identifiers are out of order")
|
||||
}
|
||||
builder.model.sourcePayloads = append(builder.model.sourcePayloads, historySourcePayload{
|
||||
kind: historySourceSummaryPayload, path: path.clone(), origin: cloneOrigin(origin),
|
||||
contributions: append([]historyPayloadRef(nil), contributions...),
|
||||
})
|
||||
return payload
|
||||
}
|
||||
|
||||
func (builder *historyBuilder) sourceContributions(path Path, summary Origin) []historyPayloadRef {
|
||||
var contributions []historyPayloadRef
|
||||
seen := make(map[historyPayloadRef]struct{})
|
||||
for _, observationID := range builder.model.observationsByPointer[path.String()] {
|
||||
observation := builder.model.observations[observationID]
|
||||
if observation.phase != historyPhaseSources || observation.role != historyRoleContribution || !sameConcreteHistoryPath(path, observation.path) {
|
||||
continue
|
||||
}
|
||||
attribution, ok := builder.model.resolveAttribution(observation.attributionRef)
|
||||
if !ok || !sourceLocationsContainedBy(attribution.origin, summary) {
|
||||
continue
|
||||
}
|
||||
if observation.payload.id < 0 || observation.payload.id >= len(builder.model.sourcePayloads) {
|
||||
continue
|
||||
}
|
||||
payload := builder.model.sourcePayloads[observation.payload.id]
|
||||
if payload.kind != historySourceApplicationPayload {
|
||||
continue
|
||||
}
|
||||
local, ok := historyApplicationLocalPath(payload.application, path)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if _, exists := documentAtPath(payload.application.value, local); !exists {
|
||||
continue
|
||||
}
|
||||
if _, exists := seen[observation.payload]; exists {
|
||||
continue
|
||||
}
|
||||
seen[observation.payload] = struct{}{}
|
||||
contributions = append(contributions, observation.payload)
|
||||
}
|
||||
return contributions
|
||||
}
|
||||
|
||||
func sourceLocationsContainedBy(candidate, summary Origin) bool {
|
||||
if len(candidate.Locations) == 0 {
|
||||
return false
|
||||
}
|
||||
available := make(map[Location]struct{}, len(summary.Locations))
|
||||
for _, location := range summary.Locations {
|
||||
available[location] = struct{}{}
|
||||
}
|
||||
for _, location := range candidate.Locations {
|
||||
if _, found := available[location]; !found {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func sourceApplicationOrigin(application historyApplication, node *document.Node) Origin {
|
||||
origin := cloneOrigin(application.origin)
|
||||
origin.Layer = application.layer
|
||||
|
||||
Reference in New Issue
Block a user