summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2014-01-02 04:31:34 (GMT)
committerNico Weber <nicolasweber@gmx.de>2014-01-02 04:31:34 (GMT)
commitb2e6fcf7031cfaf995c65820d14d4aa390daf9fb (patch)
treefebb947ed184e0bff21fa0556adc941c2dca4c82 /src
parent38db96cba7886aeaec7f9af7f5f2eb960d3e1175 (diff)
downloadNinja-b2e6fcf7031cfaf995c65820d14d4aa390daf9fb.zip
Ninja-b2e6fcf7031cfaf995c65820d14d4aa390daf9fb.tar.gz
Ninja-b2e6fcf7031cfaf995c65820d14d4aa390daf9fb.tar.bz2
Remove dead entries in .ninja_log and .ninja_deps while recompacting.
For .ninja_deps, remove objects that have no in-edges or whose in-edges do not have a "deps" attribute. (This matches the behaviour of `-t deps`). BuildLog doesn't know about state, so let its recompact method take delegate that decides is a path is life or not, and implement it in NinjaMain.
Diffstat (limited to 'src')
-rw-r--r--src/build_log.cc15
-rw-r--r--src/build_log.h8
-rw-r--r--src/deps_log.cc7
-rw-r--r--src/ninja.cc11
4 files changed, 33 insertions, 8 deletions
diff --git a/src/build_log.cc b/src/build_log.cc
index b92a06f..825a8f5 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -108,9 +108,9 @@ BuildLog::~BuildLog() {
Close();
}
-bool BuildLog::OpenForWrite(const string& path, string* err) {
+bool BuildLog::OpenForWrite(const string& path, IsDead* is_dead, string* err) {
if (needs_recompaction_) {
- if (!Recompact(path, err))
+ if (!Recompact(path, is_dead, err))
return false;
}
@@ -350,7 +350,7 @@ bool BuildLog::WriteEntry(FILE* f, const LogEntry& entry) {
entry.output.c_str(), entry.command_hash) > 0;
}
-bool BuildLog::Recompact(const string& path, string* err) {
+bool BuildLog::Recompact(const string& path, IsDead* is_dead, string* err) {
METRIC_RECORD(".ninja_log recompact");
printf("Recompacting log...\n");
@@ -368,7 +368,13 @@ bool BuildLog::Recompact(const string& path, string* err) {
return false;
}
+ vector<StringPiece> dead_outputs;
for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) {
+ if (is_dead->IsPathDead(i->first)) {
+ dead_outputs.push_back(i->first);
+ continue;
+ }
+
if (!WriteEntry(f, *i->second)) {
*err = strerror(errno);
fclose(f);
@@ -376,6 +382,9 @@ bool BuildLog::Recompact(const string& path, string* err) {
}
}
+ for (size_t i = 0; i < dead_outputs.size(); ++i)
+ entries_.erase(dead_outputs[i]);
+
fclose(f);
if (unlink(path.c_str()) < 0) {
*err = strerror(errno);
diff --git a/src/build_log.h b/src/build_log.h
index eeac5b3..bb474fc 100644
--- a/src/build_log.h
+++ b/src/build_log.h
@@ -25,6 +25,10 @@ using namespace std;
struct Edge;
+struct IsDead {
+ virtual bool IsPathDead(StringPiece s) = 0;
+};
+
/// Store a log of every command ran for every build.
/// It has a few uses:
///
@@ -36,7 +40,7 @@ struct BuildLog {
BuildLog();
~BuildLog();
- bool OpenForWrite(const string& path, string* err);
+ bool OpenForWrite(const string& path, IsDead* is_dead, string* err); // XXX
bool RecordCommand(Edge* edge, int start_time, int end_time,
TimeStamp restat_mtime = 0);
void Close();
@@ -72,7 +76,7 @@ struct BuildLog {
bool WriteEntry(FILE* f, const LogEntry& entry);
/// Rewrite the known log entries, throwing away old data.
- bool Recompact(const string& path, string* err);
+ bool Recompact(const string& path, IsDead* is_dead, string* err); // XXX
typedef ExternalStringHashMap<LogEntry*>::Type Entries;
const Entries& entries() const { return entries_; }
diff --git a/src/deps_log.cc b/src/deps_log.cc
index 4f1214a..0a3f7e5 100644
--- a/src/deps_log.cc
+++ b/src/deps_log.cc
@@ -325,6 +325,13 @@ bool DepsLog::Recompact(const string& path, string* err) {
Deps* deps = deps_[old_id];
if (!deps) continue; // If nodes_[old_id] is a leaf, it has no deps.
+ Node* n = nodes_[old_id];
+ Edge* e = n->in_edge();
+ // FIXME: move this condition to a helper: (also used in src/ninja.cc)
+ if (!e || e->GetBinding("deps").empty()) {
+ continue;
+ }
+
if (!new_log.RecordDeps(nodes_[old_id], deps->mtime,
deps->node_count, deps->nodes)) {
new_log.Close();
diff --git a/src/ninja.cc b/src/ninja.cc
index a313ecb..298d993 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -68,7 +68,7 @@ struct Options {
/// The Ninja main() loads up a series of data structures; various tools need
/// to poke into these, so store them as fields on an object.
-struct NinjaMain {
+struct NinjaMain : public IsDead {
NinjaMain(const char* ninja_command, const BuildConfig& config) :
ninja_command_(ninja_command), config_(config) {}
@@ -137,6 +137,11 @@ struct NinjaMain {
/// Dump the output requested by '-d stats'.
void DumpMetrics();
+
+ virtual bool IsPathDead(StringPiece s) {
+ Node* n = state_.LookupNode(s);
+ return !n || !n->in_edge();
+ }
};
/// Subtools, accessible via "-t foo".
@@ -789,14 +794,14 @@ bool NinjaMain::OpenBuildLog(bool recompact_only) {
}
if (recompact_only) {
- bool success = build_log_.Recompact(log_path, &err);
+ bool success = build_log_.Recompact(log_path, this, &err);
if (!success)
Error("failed recompaction: %s", err.c_str());
return success;
}
if (!config_.dry_run) {
- if (!build_log_.OpenForWrite(log_path, &err)) {
+ if (!build_log_.OpenForWrite(log_path, this, &err)) {
Error("opening build log: %s", err.c_str());
return false;
}