From 3b4f5d6acae1338e8f188d02b6348b0c20727a16 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 31 Jul 2014 16:35:47 +0200 Subject: Speed up artifact removal. The current recursive algorithm for removing an artifact from the input set of all rule nodes, while admittedly very l33t-looking, results in a quasi-infinite loop when a larger number of artifacts are to be removed. Instead, we now simply iterate over the list of nodes. A further speed-up might be possible by doing batch changes, but this one solves the immediate problem. Change-Id: Id3c19321c82d5097e58b1b312c8717c59dc06eb3 Reviewed-by: Joerg Bornemann --- src/lib/corelib/buildgraph/projectbuilddata.cpp | 54 +++++++------------------ 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index 3f8634b51..0e846ae53 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -261,48 +261,24 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact, removeArtifact(artifact, logger, removeFromDisk, removeFromProduct); } -template -void forEachRuleNode(BuildGraphNode *n, const Func &f) +static void removeFromRuleNodes(Artifact *artifact, const Logger &logger) { - if (n->type() != BuildGraphNode::RuleNodeType) - return; - f(static_cast(n)); - foreach (BuildGraphNode *c, n->children) - forEachRuleNode(c, f); -} - -template -void forEachRuleNode(const TopLevelProject *project, const Func &f) -{ - foreach (const ResolvedProductPtr &product, project->allProducts()) { + foreach (const ResolvedProductPtr &product, + artifact->product->topLevelProject()->allProducts()) { if (!product->buildData) continue; - foreach (BuildGraphNode *n, product->buildData->roots) - forEachRuleNode(n, f); - } -} - -class RemoveOldInputArtifactFromRuleNode -{ -public: - RemoveOldInputArtifactFromRuleNode(Artifact *artifact, const Logger &logger) - : m_artifact(artifact), m_logger(logger) - { - } - - void operator()(RuleNode *ruleNode) const - { - if (m_logger.traceEnabled()) { - m_logger.qbsTrace() << "[BG] remove old input " << m_artifact->filePath() - << " from rule " << ruleNode->rule()->toString(); + foreach (BuildGraphNode *n, product->buildData->nodes) { + if (n->type() != BuildGraphNode::RuleNodeType) + continue; + RuleNode * const ruleNode = static_cast(n); + if (logger.traceEnabled()) { + logger.qbsTrace() << "[BG] remove old input " << artifact->filePath() + << " from rule " << ruleNode->rule()->toString(); + } + ruleNode->removeOldInputArtifact(artifact); } - ruleNode->removeOldInputArtifact(m_artifact); } - -private: - Artifact * const m_artifact; - const Logger &m_logger; -}; +} void ProjectBuildData::removeArtifact(Artifact *artifact, const Logger &logger, bool removeFromDisk, bool removeFromProduct) @@ -318,9 +294,7 @@ void ProjectBuildData::removeArtifact(Artifact *artifact, artifact->product->buildData->roots.remove(artifact); removeArtifactFromSet(artifact, artifact->product->buildData->artifactsByFileTag); } - forEachRuleNode(artifact->product->topLevelProject(), - RemoveOldInputArtifactFromRuleNode(artifact, logger)); - + removeFromRuleNodes(artifact, logger); disconnectArtifact(artifact, logger); if (artifact->transformer) { artifact->product->unregisterArtifactWithChangedInputs(artifact); -- cgit v1.2.3