aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@digia.com>2014-07-24 19:12:16 +0200
committerJoerg Bornemann <joerg.bornemann@digia.com>2014-07-30 14:00:57 +0200
commitfd49db9b33c0f54255d92c0d882a4f18c20a5ef3 (patch)
treef01a43527e41bfced20f0fc77e2fe1ed3ee73d91
parent472a0e505a78fddf5d7ce02b2c6ef8f859926b3e (diff)
fix calculation of old inputs for dynamic rules
Instead of deducing the old inputs of a rule from the inputs of its created transformers, we hold a dedicated list of old inputs, because the former approach doesn't work for dynamic rules. This fixes a speed regression introduced in 32c4d3d7. The outputArtifacts script of dynamic rules was always run on compatible inputs that were not input of transformers, e.g. C++ sources that don't have a Q_OBJECT macro. Change-Id: I2d43fa7c91ed9084bd27dc9b948c06152bfce726 Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
-rw-r--r--src/lib/corelib/buildgraph/artifactset.cpp6
-rw-r--r--src/lib/corelib/buildgraph/artifactset.h3
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp45
-rw-r--r--src/lib/corelib/buildgraph/rulenode.cpp30
-rw-r--r--src/lib/corelib/buildgraph/rulenode.h4
-rw-r--r--src/lib/corelib/tools/persistence.cpp2
6 files changed, 62 insertions, 28 deletions
diff --git a/src/lib/corelib/buildgraph/artifactset.cpp b/src/lib/corelib/buildgraph/artifactset.cpp
index c44f5e4b9..0010e81fe 100644
--- a/src/lib/corelib/buildgraph/artifactset.cpp
+++ b/src/lib/corelib/buildgraph/artifactset.cpp
@@ -47,6 +47,12 @@ ArtifactSet::ArtifactSet(const QSet<Artifact *> &other)
{
}
+ArtifactSet &ArtifactSet::unite(const ArtifactSet &other)
+{
+ QSet::unite(other);
+ return *this;
+}
+
ArtifactSet ArtifactSet::fromNodeSet(const NodeSet &nodes)
{
ArtifactSet result;
diff --git a/src/lib/corelib/buildgraph/artifactset.h b/src/lib/corelib/buildgraph/artifactset.h
index 092e9e8a2..696859649 100644
--- a/src/lib/corelib/buildgraph/artifactset.h
+++ b/src/lib/corelib/buildgraph/artifactset.h
@@ -44,6 +44,9 @@ public:
ArtifactSet();
ArtifactSet(const ArtifactSet &other);
ArtifactSet(const QSet<Artifact *> &other);
+
+ ArtifactSet &unite(const ArtifactSet &other);
+
static ArtifactSet fromNodeSet(const NodeSet &nodes);
static ArtifactSet fromNodeList(const QList<Artifact *> &lst);
};
diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp
index 2a4fc812f..6af68caa3 100644
--- a/src/lib/corelib/buildgraph/projectbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp
@@ -261,6 +261,49 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact,
removeArtifact(artifact, logger, removeFromDisk, removeFromProduct);
}
+template <class Func>
+void forEachRuleNode(BuildGraphNode *n, const Func &f)
+{
+ if (n->type() != BuildGraphNode::RuleNodeType)
+ return;
+ f(static_cast<RuleNode *>(n));
+ foreach (BuildGraphNode *c, n->children)
+ forEachRuleNode(c, f);
+}
+
+template <class Func>
+void forEachRuleNode(const TopLevelProject *project, const Func &f)
+{
+ foreach (const ResolvedProductPtr &product, project->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();
+ }
+ 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)
{
@@ -275,6 +318,8 @@ void ProjectBuildData::removeArtifact(Artifact *artifact,
artifact->product->buildData->roots.remove(artifact);
removeArtifactFromSet(artifact, artifact->product->buildData->artifactsByFileTag);
}
+ forEachRuleNode(artifact->product->topLevelProject(),
+ RemoveOldInputArtifactFromRuleNode(artifact, logger));
disconnectArtifact(artifact, logger);
if (artifact->transformer) {
diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp
index 00454d080..3ea324238 100644
--- a/src/lib/corelib/buildgraph/rulenode.cpp
+++ b/src/lib/corelib/buildgraph/rulenode.cpp
@@ -65,10 +65,9 @@ QString RuleNode::toString() const
void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs,
ApplicationResult *result)
{
- const ArtifactSet oldInputs = oldInputArtifacts();
ArtifactSet allCompatibleInputs = currentInputArtifacts();
- const ArtifactSet addedInputs = allCompatibleInputs - oldInputs;
- const ArtifactSet removedInputs = oldInputs - allCompatibleInputs;
+ const ArtifactSet addedInputs = allCompatibleInputs - m_oldInputArtifacts;
+ const ArtifactSet removedInputs = m_oldInputArtifacts - allCompatibleInputs;
result->upToDate = changedInputs.isEmpty() && addedInputs.isEmpty() && removedInputs.isEmpty();
ArtifactSet inputs = changedInputs;
@@ -108,6 +107,7 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs,
if (!inputs.isEmpty()) {
RulesApplicator applicator(product, logger);
result->createdNodes = applicator.applyRuleInEvaluationContext(m_rule, inputs);
+ m_oldInputArtifacts.unite(inputs);
}
}
@@ -115,34 +115,14 @@ void RuleNode::load(PersistentPool &pool)
{
BuildGraphNode::load(pool);
m_rule = pool.idLoadS<Rule>();
+ pool.loadContainer(m_oldInputArtifacts);
}
void RuleNode::store(PersistentPool &pool) const
{
BuildGraphNode::store(pool);
pool.store(m_rule);
-}
-
-QList<TransformerPtr> RuleNode::createdTransformers() const
-{
- QList<TransformerPtr> lst;
- foreach (BuildGraphNode *parent, parents) {
- if (parent->type() != ArtifactNodeType)
- continue;
- Artifact *artifact = static_cast<Artifact *>(parent);
- if (!artifact->transformer || artifact->transformer->rule != m_rule)
- continue;
- lst.append(artifact->transformer);
- }
- return lst;
-}
-
-ArtifactSet RuleNode::oldInputArtifacts() const
-{
- ArtifactSet s;
- foreach (const TransformerPtr &t, createdTransformers())
- s += t->inputs;
- return s;
+ pool.storeContainer(m_oldInputArtifacts);
}
ArtifactSet RuleNode::currentInputArtifacts() const
diff --git a/src/lib/corelib/buildgraph/rulenode.h b/src/lib/corelib/buildgraph/rulenode.h
index 027094211..fcc0076c6 100644
--- a/src/lib/corelib/buildgraph/rulenode.h
+++ b/src/lib/corelib/buildgraph/rulenode.h
@@ -60,17 +60,17 @@ public:
};
void apply(const Logger &logger, const ArtifactSet &changedInputs, ApplicationResult *result);
+ void removeOldInputArtifact(Artifact *artifact) { m_oldInputArtifacts.remove(artifact); }
protected:
void load(PersistentPool &pool);
void store(PersistentPool &pool) const;
private:
- QList<TransformerPtr> createdTransformers() const;
- ArtifactSet oldInputArtifacts() const;
ArtifactSet currentInputArtifacts() const;
RuleConstPtr m_rule;
+ ArtifactSet m_oldInputArtifacts;
};
} // namespace Internal
diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp
index 09834943c..0264353d3 100644
--- a/src/lib/corelib/tools/persistence.cpp
+++ b/src/lib/corelib/tools/persistence.cpp
@@ -40,7 +40,7 @@
namespace qbs {
namespace Internal {
-static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-73";
+static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-74";
PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger)
{