diff options
author | Evan Martin <martine@danga.com> | 2013-01-07 18:59:27 (GMT) |
---|---|---|
committer | Evan Martin <martine@danga.com> | 2013-04-08 22:01:36 (GMT) |
commit | ab218230c4c6c3f0bb2a26215d1ac09e397e6065 (patch) | |
tree | 46bbac03e80bd3fedf223554d8585955af8f36c7 | |
parent | 58c7139b9f404e18097d4f3ef6adcd49a01e3d73 (diff) | |
download | Ninja-ab218230c4c6c3f0bb2a26215d1ac09e397e6065.zip Ninja-ab218230c4c6c3f0bb2a26215d1ac09e397e6065.tar.gz Ninja-ab218230c4c6c3f0bb2a26215d1ac09e397e6065.tar.bz2 |
don't write out deps entries if nothing changed
Shortcuts a common case.
-rw-r--r-- | src/deps_log.cc | 32 | ||||
-rw-r--r-- | src/deps_log_test.cc | 46 |
2 files changed, 76 insertions, 2 deletions
diff --git a/src/deps_log.cc b/src/deps_log.cc index da6cd93..0f10b5c 100644 --- a/src/deps_log.cc +++ b/src/deps_log.cc @@ -50,15 +50,43 @@ bool DepsLog::OpenForWrite(const string& path, string* err) { bool DepsLog::RecordDeps(Node* node, TimeStamp mtime, const vector<Node*>& nodes) { + // Track whether there's any new data to be recorded. + bool made_change = false; + // Assign ids to all nodes that are missing one. - if (node->id() < 0) + if (node->id() < 0) { RecordId(node); + made_change = true; + } for (vector<Node*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i) { - if ((*i)->id() < 0) + if ((*i)->id() < 0) { RecordId(*i); + made_change = true; + } + } + + // See if the new data is different than the existing data, if any. + if (!made_change) { + Deps* deps = GetDeps(node); + if (!deps || + deps->mtime != mtime || + deps->node_count != (int)nodes.size()) { + made_change = true; + } else { + for (int i = 0; i < (int)nodes.size(); ++i) { + if (deps->nodes[i] != nodes[i]) { + made_change = true; + break; + } + } + } } + // Don't write anything if there's no new info. + if (!made_change) + return true; + uint16_t size = 4 * (1 + 1 + (uint16_t)nodes.size()); size |= 0x8000; // Deps record: set high bit. fwrite(&size, 2, 1, file_); diff --git a/src/deps_log_test.cc b/src/deps_log_test.cc index 3f47fef..e411e12 100644 --- a/src/deps_log_test.cc +++ b/src/deps_log_test.cc @@ -76,4 +76,50 @@ TEST_F(DepsLogTest, WriteRead) { ASSERT_EQ("bar.h", deps->nodes[1]->path()); } +// Verify that adding the same deps twice doesn't grow the file. +TEST_F(DepsLogTest, DoubleEntry) { + // Write some deps to the file and grab its size. + int file_size; + { + State state; + DepsLog log; + string err; + EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err)); + ASSERT_EQ("", err); + + vector<Node*> deps; + deps.push_back(state.GetNode("foo.h")); + deps.push_back(state.GetNode("bar.h")); + log.RecordDeps(state.GetNode("out.o"), 1, deps); + log.Close(); + + struct stat st; + ASSERT_EQ(0, stat(kTestFilename, &st)); + file_size = (int)st.st_size; + ASSERT_GT(file_size, 0); + } + + // Now reload the file, and readd the same deps. + { + State state; + DepsLog log; + string err; + EXPECT_TRUE(log.Load(kTestFilename, &state, &err)); + + EXPECT_TRUE(log.OpenForWrite(kTestFilename, &err)); + ASSERT_EQ("", err); + + vector<Node*> deps; + deps.push_back(state.GetNode("foo.h")); + deps.push_back(state.GetNode("bar.h")); + log.RecordDeps(state.GetNode("out.o"), 1, deps); + log.Close(); + + struct stat st; + ASSERT_EQ(0, stat(kTestFilename, &st)); + int file_size_2 = (int)st.st_size; + ASSERT_EQ(file_size, file_size_2); + } +} + } // anonymous namespace |