Index sequence assembly and history lookups
This commit is contained in:
@@ -45,11 +45,12 @@ func (c *retainedNodeCounter) add(root *document.Node) bool {
|
||||
// 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
|
||||
sequences []sequenceHistoryContribution
|
||||
layer Layer
|
||||
path Path
|
||||
value *document.Node
|
||||
origin Origin
|
||||
sequences []sequenceHistoryContribution
|
||||
sequencesByPath map[string]sequenceHistoryContribution
|
||||
}
|
||||
|
||||
func cloneHistoryApplications(values []historyApplication) []historyApplication {
|
||||
@@ -62,6 +63,7 @@ func cloneHistoryApplications(values []historyApplication) []historyApplication
|
||||
layer: value.layer, path: value.path.clone(), value: value.value,
|
||||
origin: cloneOrigin(value.origin), sequences: cloneSequenceHistoryContributions(value.sequences),
|
||||
}
|
||||
cloned[index].sequencesByPath = indexSequenceHistoryContributions(cloned[index].sequences)
|
||||
}
|
||||
return cloned
|
||||
}
|
||||
@@ -86,7 +88,7 @@ func walkHistoryApplication(application historyApplication, visit func(local, ef
|
||||
walk(entry.Value, local.Key(entry.Key), effective.Key(entry.Key))
|
||||
}
|
||||
case document.Sequence:
|
||||
contribution, projected := sequenceHistoryAt(application.sequences, local)
|
||||
contribution, projected := sequenceHistoryAt(application.sequencesByPath, local)
|
||||
for index, child := range node.Sequence {
|
||||
effectiveIndex := index
|
||||
if projected {
|
||||
@@ -108,7 +110,7 @@ func historyApplicationLocalPath(application historyApplication, effective Path)
|
||||
}
|
||||
local := Path{}
|
||||
for _, segment := range relative.segments {
|
||||
if contribution, found := sequenceHistoryAt(application.sequences, local); found {
|
||||
if contribution, found := sequenceHistoryAt(application.sequencesByPath, local); found {
|
||||
index, valid := schemaIndex(segment)
|
||||
if !valid || segment.kind == pathSegmentKey || index < contribution.offset || index >= contribution.offset+contribution.length {
|
||||
return Path{}, false
|
||||
@@ -201,7 +203,7 @@ func pathsIntersect(left, right Path) bool {
|
||||
|
||||
func applyHistoryApplication(root **document.Node, application historyApplication, index *mappingIndex) {
|
||||
if application.path.String() == "" {
|
||||
mergeHistoryDocumentAtPath(root, application.value, Path{}, index, application.sequences)
|
||||
mergeHistoryDocumentAtPath(root, application.value, Path{}, index, application.sequencesByPath)
|
||||
return
|
||||
}
|
||||
mergeHistoryAtPath(root, application.path, application.value, index)
|
||||
@@ -211,7 +213,7 @@ func mergeHistoryDocument(target **document.Node, incoming *document.Node, index
|
||||
mergeHistoryDocumentAtPath(target, incoming, Path{}, index, nil)
|
||||
}
|
||||
|
||||
func mergeHistoryDocumentAtPath(target **document.Node, incoming *document.Node, path Path, index *mappingIndex, sequences []sequenceHistoryContribution) {
|
||||
func mergeHistoryDocumentAtPath(target **document.Node, incoming *document.Node, path Path, index *mappingIndex, sequences map[string]sequenceHistoryContribution) {
|
||||
if incoming == nil {
|
||||
return
|
||||
}
|
||||
@@ -236,13 +238,20 @@ func mergeHistoryDocumentAtPath(target **document.Node, incoming *document.Node,
|
||||
}
|
||||
}
|
||||
|
||||
func sequenceHistoryAt(contributions []sequenceHistoryContribution, path Path) (sequenceHistoryContribution, bool) {
|
||||
for _, contribution := range contributions {
|
||||
if contribution.path.String() == path.String() {
|
||||
return contribution, true
|
||||
}
|
||||
func sequenceHistoryAt(contributions map[string]sequenceHistoryContribution, path Path) (sequenceHistoryContribution, bool) {
|
||||
contribution, found := contributions[path.String()]
|
||||
return contribution, found
|
||||
}
|
||||
|
||||
func indexSequenceHistoryContributions(values []sequenceHistoryContribution) map[string]sequenceHistoryContribution {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
return sequenceHistoryContribution{}, false
|
||||
index := make(map[string]sequenceHistoryContribution, len(values))
|
||||
for _, value := range values {
|
||||
index[value.path.String()] = value
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
func applySequenceHistory(target **document.Node, incoming *document.Node, contribution sequenceHistoryContribution) {
|
||||
|
||||
Reference in New Issue
Block a user