Schedule underlay groups as dependency forests
This commit is contained in:
@@ -158,14 +158,23 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
initialBytes, initialNodes := accounting.bytes, accounting.nodes
|
||||
visited := make(map[resourceIdentity]importRoute)
|
||||
hostToken := &namespaceToken{}
|
||||
nativeAnchors := make(map[*namespaceToken]string)
|
||||
for inputIndex, contribution := range group.inputs {
|
||||
if token := nativeTokenForLoadInput(contribution); token != nil {
|
||||
if _, exists := nativeAnchors[token]; !exists {
|
||||
nativeAnchors[token] = explicitNamespaceAnchor(index, inputIndex+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
var scopes []acquisitionScope
|
||||
inclusionGraph := newImportInclusionGraph()
|
||||
var sources []SourceInfo
|
||||
var contexts map[string]ResourceContext
|
||||
for _, contribution := range group.inputs {
|
||||
for inputIndex, contribution := range group.inputs {
|
||||
options := Options[struct{}]{
|
||||
Imports: contribution.imports, Filesystem: contribution.filesystem,
|
||||
Definition: Definition[struct{}]{Version: rule}, destination: contribution.destination.clone(),
|
||||
placementMode: contribution.placementMode, sequencePolicy: policy,
|
||||
placementMode: contribution.placementMode, sequencePolicy: policy, deferAssembly: true,
|
||||
}
|
||||
acquired, diagnostics := assembleBaseInputTrackedForRole(contribution.source, options, contribution.destination, accounting, visited, hostToken, versionState, sourceVersionContribution)
|
||||
for _, source := range acquired.sources {
|
||||
@@ -177,16 +186,37 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
if len(diagnostics) != 0 {
|
||||
return nil, sources, contexts, projectPriorInputDiagnosticPaths(diagnostics, scopes)
|
||||
}
|
||||
if acquired.document == nil {
|
||||
if acquired.document == nil && len(acquired.acquisition) == 0 {
|
||||
continue
|
||||
}
|
||||
scopes = append(scopes, cloneAcquisitionScopes(acquired.acquisition)...)
|
||||
anchors := importNamespaceAnchors{
|
||||
kind: "host", host: explicitNamespaceAnchor(index, 0),
|
||||
input: explicitNamespaceAnchor(index, inputIndex+1),
|
||||
}
|
||||
if token := nativeTokenForLoadInput(contribution); token != nil {
|
||||
anchors.kind = "native"
|
||||
anchors.native = nativeAnchors[token]
|
||||
}
|
||||
inputScopes := cloneAcquisitionScopes(acquired.acquisition)
|
||||
inputGraph := newImportInclusionGraph()
|
||||
if acquired.composition != nil {
|
||||
inputGraph = acquired.composition.importGraph
|
||||
}
|
||||
inputGraph, keyMap := reanchorImportGraph(inputGraph, anchors)
|
||||
for scopeIndex := range inputScopes {
|
||||
reanchorAcquisitionScope(&inputScopes[scopeIndex], keyMap, anchors)
|
||||
}
|
||||
scopes = append(scopes, inputScopes...)
|
||||
mergeImportInclusionGraph(&inclusionGraph, inputGraph)
|
||||
}
|
||||
groupScope := scheduleAcquisitionGroup(scopes, inclusionGraph)
|
||||
traversal := importTraversal{accounting: accounting, limits: defaultImportLimits(), rule: rule, importGraph: inclusionGraph}
|
||||
if diagnostics := traversal.composePendingItems(&groupScope); len(diagnostics) != 0 {
|
||||
return nil, sources, contexts, diagnostics
|
||||
}
|
||||
var documents []*document.Node
|
||||
for _, scope := range scopes {
|
||||
for _, contribution := range scope.contributions {
|
||||
documents = append(documents, contribution.document)
|
||||
}
|
||||
for _, contribution := range groupScope.contributions {
|
||||
documents = append(documents, contribution.document)
|
||||
}
|
||||
if len(documents) == 0 {
|
||||
return nil, sources, contexts, nil
|
||||
@@ -197,6 +227,18 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
}
|
||||
if composition != nil && rule != nil {
|
||||
ranges := indexSequenceRanges(composition.sequenceRanges)
|
||||
for sourceIndex, document := range documents {
|
||||
if groupScope.contributions[sourceIndex].role == importRoleMain {
|
||||
continue
|
||||
}
|
||||
if node := fragmentVersionClaimWithIndex(document, rule, sourceIndex, ranges); node != nil {
|
||||
location := publicLocation(node.Location)
|
||||
return nil, sources, contexts, []Diagnostic{{
|
||||
Code: CodeImportVersion, Severity: SeverityError, Path: rule.Path.clone(),
|
||||
Message: "imported fragments cannot contribute to the schema-version path", Primary: &location,
|
||||
}}
|
||||
}
|
||||
}
|
||||
for sourceIndex, document := range documents {
|
||||
if node := fragmentVersionClaimWithIndex(document, rule, sourceIndex, ranges); node != nil {
|
||||
location := publicLocation(node.Location)
|
||||
@@ -209,13 +251,14 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
}
|
||||
composition.inputBytes = accounting.bytes - initialBytes
|
||||
composition.inputNodes = accounting.nodes - initialNodes
|
||||
composition.acquisition = cloneAcquisitionScopes(scopes)
|
||||
var projectionScope acquisitionScope
|
||||
for _, scope := range scopes {
|
||||
projectionScope.contributions = append(projectionScope.contributions, scope.contributions...)
|
||||
groupScope.owner = importNodeKey{namespaceKind: "group", namespaceAnchor: explicitNamespaceAnchor(index, 0), resourceKind: "scope"}
|
||||
for contributionIndex := range groupScope.contributions {
|
||||
groupScope.contributions[contributionIndex].scopeOwner = groupScope.owner
|
||||
}
|
||||
projectNestedEvidence(composition, projectionScope)
|
||||
projectAcquiredDestinations(composition, projectionScope, sources)
|
||||
composition.acquisition = []acquisitionScope{cloneAcquisitionScope(groupScope)}
|
||||
composition.importGraph = inclusionGraph.clone()
|
||||
projectNestedEvidence(composition, groupScope)
|
||||
projectAcquiredDestinations(composition, groupScope, sources)
|
||||
for pointer, origin := range composition.origins {
|
||||
origin.Layer = LayerUnderlay
|
||||
composition.origins[pointer] = origin
|
||||
@@ -225,3 +268,13 @@ func acquireUnderlayGroupWithPolicyVersion(group loadGroup, index int, rule *Ver
|
||||
}
|
||||
return composition, sources, contexts, nil
|
||||
}
|
||||
|
||||
func nativeTokenForLoadInput(input loadInput) *namespaceToken {
|
||||
if input.source.kind == sourceFilesystem && input.source.namespace != nil {
|
||||
return input.source.namespace.token
|
||||
}
|
||||
if input.filesystem != nil && input.filesystem.FS != nil && input.filesystem.FS.namespace != nil {
|
||||
return input.filesystem.FS.namespace.token
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user