Avoid repeated prefix scans when projecting item policies
This commit is contained in:
@@ -961,17 +961,28 @@ func projectNestedCollectionPolicies(composed *composedDocument, scope acquisiti
|
||||
return
|
||||
}
|
||||
baseOffsets := make(map[string]int)
|
||||
var prefixLengths map[string]int
|
||||
for sourceIndex, contribution := range scope.contributions {
|
||||
if prefixLengths != nil && sourceIndex > 0 {
|
||||
addSequencePrefixLengths(scope.contributions[sourceIndex-1].document, Path{}, prefixLengths)
|
||||
}
|
||||
if contribution.nested == nil || len(contribution.nested.collectionPolicies.collections) == 0 {
|
||||
continue
|
||||
}
|
||||
itemIndex := priorSequenceLength([]acquisitionScope{{contributions: scope.contributions[:sourceIndex]}}, contribution.destination)
|
||||
if assigned, found := ranges[sequenceRangeKey{sourceIndex: sourceIndex, path: contribution.destination.String()}]; found {
|
||||
if projected, ok := assigned.outputForInput(0); ok {
|
||||
itemIndex = projected
|
||||
}
|
||||
}
|
||||
key := contribution.destination.String()
|
||||
assigned := ranges[sequenceRangeKey{sourceIndex: sourceIndex, path: key}]
|
||||
itemIndex, found := assigned.outputForInput(0)
|
||||
if !found {
|
||||
// Normal composition supplies the assignment directly. For a
|
||||
// handoff without ranges, scan each preceding tree only once.
|
||||
if prefixLengths == nil {
|
||||
prefixLengths = make(map[string]int)
|
||||
for _, previous := range scope.contributions[:sourceIndex] {
|
||||
addSequencePrefixLengths(previous.document, Path{}, prefixLengths)
|
||||
}
|
||||
}
|
||||
itemIndex = prefixLengths[key]
|
||||
}
|
||||
base, initialized := baseOffsets[key]
|
||||
policy, _ := composed.collectionPolicies.at(contribution.destination)
|
||||
if !initialized {
|
||||
@@ -986,6 +997,20 @@ func projectNestedCollectionPolicies(composed *composedDocument, scope acquisiti
|
||||
}
|
||||
}
|
||||
|
||||
func addSequencePrefixLengths(node *document.Node, path Path, lengths map[string]int) {
|
||||
if node == nil {
|
||||
return
|
||||
}
|
||||
if node.Kind == document.Sequence {
|
||||
lengths[path.String()] += len(node.Sequence)
|
||||
return
|
||||
}
|
||||
// Contribution destinations select mapping paths, not sequence members.
|
||||
for _, entry := range node.Mapping {
|
||||
addSequencePrefixLengths(entry.Value, path.Key(entry.Key), lengths)
|
||||
}
|
||||
}
|
||||
|
||||
func projectNestedOrigins(target map[string]Origin, root *document.Node, origins map[string]Origin, prefix Path) {
|
||||
var visit func(*document.Node, Path)
|
||||
visit = func(node *document.Node, path Path) {
|
||||
|
||||
Reference in New Issue
Block a user