Schedule underlay groups as dependency forests
This commit is contained in:
@@ -80,12 +80,16 @@ func loadImportedDocumentsTrackedWithVersion(source Source, context *FilesystemC
|
||||
}
|
||||
|
||||
func loadImportedDocumentsTrackedWithProcessing(source Source, context *FilesystemContext, main parsedSource, destination Path, rule *VersionRule, limits importLimits, accounting *importAccounting, visited map[resourceIdentity]importRoute, hostToken *namespaceToken, versionState *sourceVersionState, processing *sourceVersionProcessingResult, policy sequencePolicy) (*composedDocument, []SourceInfo, []Diagnostic) {
|
||||
return loadImportedDocumentsTrackedWithProcessingDeferred(source, context, main, destination, rule, limits, accounting, visited, hostToken, versionState, processing, policy, false)
|
||||
}
|
||||
|
||||
func loadImportedDocumentsTrackedWithProcessingDeferred(source Source, context *FilesystemContext, main parsedSource, destination Path, rule *VersionRule, limits importLimits, accounting *importAccounting, visited map[resourceIdentity]importRoute, hostToken *namespaceToken, versionState *sourceVersionState, processing *sourceVersionProcessingResult, policy sequencePolicy, deferAssembly bool) (*composedDocument, []SourceInfo, []Diagnostic) {
|
||||
if nativeContext(source, context) {
|
||||
access, basePath, mainPath, diagnostic := nativeFilesystemAccess(source, context)
|
||||
if diagnostic != nil {
|
||||
return nil, sourceInfos(main.source), []Diagnostic{*diagnostic}
|
||||
}
|
||||
return loadImportedWithAccessTrackedAndProcessingPolicy(access, basePath, mainPath, main, destination, rule, limits, accounting, visited, versionState, processing, policy)
|
||||
return loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access, basePath, mainPath, main, destination, rule, limits, accounting, visited, versionState, processing, policy, deferAssembly)
|
||||
}
|
||||
rootPath, basePath, mainPath, diagnostic := importFilesystem(source, context, main)
|
||||
if diagnostic != nil {
|
||||
@@ -100,7 +104,7 @@ func loadImportedDocumentsTrackedWithProcessing(source Source, context *Filesyst
|
||||
if hostToken != nil {
|
||||
access.token = hostToken
|
||||
}
|
||||
return loadImportedWithAccessTrackedAndProcessingPolicy(access, basePath, mainPath, main, destination, rule, limits, accounting, visited, versionState, processing, policy)
|
||||
return loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access, basePath, mainPath, main, destination, rule, limits, accounting, visited, versionState, processing, policy, deferAssembly)
|
||||
}
|
||||
|
||||
func loadImportedWithAccess(access *filesystemAccess, basePath, mainPath string, main parsedSource, rule *VersionRule, limits importLimits, accounting *importAccounting) (*composedDocument, []SourceInfo, []Diagnostic) {
|
||||
@@ -124,6 +128,10 @@ func loadImportedWithAccessTrackedAndProcessing(access *filesystemAccess, basePa
|
||||
}
|
||||
|
||||
func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess, basePath, mainPath string, main parsedSource, destination Path, rule *VersionRule, limits importLimits, accounting *importAccounting, visited map[resourceIdentity]importRoute, versionState *sourceVersionState, processing *sourceVersionProcessingResult, policy sequencePolicy) (*composedDocument, []SourceInfo, []Diagnostic) {
|
||||
return loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access, basePath, mainPath, main, destination, rule, limits, accounting, visited, versionState, processing, policy, false)
|
||||
}
|
||||
|
||||
func loadImportedWithAccessTrackedAndProcessingPolicyDeferred(access *filesystemAccess, basePath, mainPath string, main parsedSource, destination Path, rule *VersionRule, limits importLimits, accounting *importAccounting, visited map[resourceIdentity]importRoute, versionState *sourceVersionState, processing *sourceVersionProcessingResult, policy sequencePolicy, deferAssembly bool) (*composedDocument, []SourceInfo, []Diagnostic) {
|
||||
if !access.contains(basePath) || (mainPath != "" && !access.contains(mainPath)) {
|
||||
_ = access.close()
|
||||
return nil, sourceInfos(main.source), []Diagnostic{importDiagnostic(CodeImportOutsideRoot, "selected source and import base must stay inside the configuration root", nil)}
|
||||
@@ -221,7 +229,9 @@ func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess,
|
||||
}
|
||||
if len(diagnostics) == 0 {
|
||||
state.scheduleAcquisitionScopes(&state.scope)
|
||||
diagnostics = state.composePendingItems(&state.scope)
|
||||
if !deferAssembly {
|
||||
diagnostics = state.composePendingItems(&state.scope)
|
||||
}
|
||||
}
|
||||
|
||||
closeErr := access.close()
|
||||
@@ -234,6 +244,27 @@ func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess,
|
||||
if closeErr != nil {
|
||||
return nil, cloneSourceInfos(state.sources), []Diagnostic{importDiagnostic(CodeImportRead, "configuration root could not be closed", nil)}
|
||||
}
|
||||
if deferAssembly {
|
||||
acquisition := state.scope
|
||||
if mainIsItem {
|
||||
localScope := state.scope
|
||||
acquisition = acquisitionScope{
|
||||
owner: mainNodeKey, destination: destination.clone(),
|
||||
contributions: []acquiredContribution{{
|
||||
source: cloneSourceInfo(mainInfo), payload: body, identity: mainNodeKey,
|
||||
role: importRoleMain, scopeOwner: mainNodeKey, destination: destination.clone(),
|
||||
processing: processing, pendingItem: &localScope,
|
||||
}},
|
||||
}
|
||||
}
|
||||
if diagnostic := reservePendingItemPlacements(&acquisition, limits, accounting); diagnostic != nil {
|
||||
return nil, cloneSourceInfos(state.sources), []Diagnostic{*diagnostic}
|
||||
}
|
||||
return &composedDocument{
|
||||
acquisition: []acquisitionScope{cloneAcquisitionScope(acquisition)},
|
||||
importGraph: state.importGraph.clone(), inputBytes: accounting.bytes, inputNodes: accounting.nodes,
|
||||
}, cloneSourceInfos(state.sources), nil
|
||||
}
|
||||
if mainIsItem {
|
||||
localScope := state.scope
|
||||
documents := make([]*document.Node, 0, len(localScope.contributions))
|
||||
@@ -313,6 +344,29 @@ func loadImportedWithAccessTrackedAndProcessingPolicy(access *filesystemAccess,
|
||||
return composed, cloneSourceInfos(state.sources), diagnostics
|
||||
}
|
||||
|
||||
func reservePendingItemPlacements(scope *acquisitionScope, limits importLimits, accounting *importAccounting) *Diagnostic {
|
||||
if scope == nil {
|
||||
return nil
|
||||
}
|
||||
for index := range scope.contributions {
|
||||
contribution := &scope.contributions[index]
|
||||
if contribution.pendingItem == nil {
|
||||
continue
|
||||
}
|
||||
placementNodes := destinationWrapperNodeCountForMode(contribution.destination, placementModeSequenceItem)
|
||||
if accounting.nodes+placementNodes > limits.nodes {
|
||||
diagnostic := importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the aggregate node limit", contribution.source.ImportedFrom)
|
||||
return &diagnostic
|
||||
}
|
||||
accounting.nodes += placementNodes
|
||||
contribution.placementCharged = true
|
||||
if diagnostic := reservePendingItemPlacements(contribution.pendingItem, limits, accounting); diagnostic != nil {
|
||||
return diagnostic
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *importTraversal) checkInitialLimits() *Diagnostic {
|
||||
if s.accounting.sources > s.limits.sources {
|
||||
value := importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the source-count limit", nil)
|
||||
@@ -609,6 +663,9 @@ func (s *importTraversal) composePendingItems(scope *acquisitionScope) []Diagnos
|
||||
if len(diagnostics) != 0 {
|
||||
return projectItemDiagnosticPaths(diagnostics, *scope, contribution.destination, index)
|
||||
}
|
||||
if diagnostic := importedVersionClaim(documents, *itemScope, completed, s.rule); diagnostic != nil {
|
||||
return []Diagnostic{*diagnostic}
|
||||
}
|
||||
completed.acquisition = []acquisitionScope{cloneAcquisitionScope(*itemScope)}
|
||||
projectNestedEvidence(completed, *itemScope)
|
||||
_, placed, err := placeDocumentWithMode(completed.root, contribution.destination, placementModeSequenceItem, contribution.payload.Location, maxDocumentDepth, maxDocumentNodes)
|
||||
@@ -616,10 +673,12 @@ func (s *importTraversal) composePendingItems(scope *acquisitionScope) []Diagnos
|
||||
return []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the source depth or node limit after destination placement", contribution.source.ImportedFrom)}
|
||||
}
|
||||
placementNodes := destinationWrapperNodeCountForMode(contribution.destination, placementModeSequenceItem)
|
||||
if s.accounting.nodes+placementNodes > s.limits.nodes {
|
||||
return []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the aggregate node limit", contribution.source.ImportedFrom)}
|
||||
if !contribution.placementCharged {
|
||||
if s.accounting.nodes+placementNodes > s.limits.nodes {
|
||||
return []Diagnostic{importDiagnostic(CodeImportLimitExceeded, "configuration exceeds the aggregate node limit", contribution.source.ImportedFrom)}
|
||||
}
|
||||
s.accounting.nodes += placementNodes
|
||||
}
|
||||
s.accounting.nodes += placementNodes
|
||||
contribution.payload = completed.root
|
||||
contribution.document = placed
|
||||
contribution.nested = completed
|
||||
|
||||
Reference in New Issue
Block a user