From ab218230c4c6c3f0bb2a26215d1ac09e397e6065 Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Mon, 7 Jan 2013 10:59:27 -0800 Subject: [PATCH] don't write out deps entries if nothing changed Shortcuts a common case. --- src/deps_log.cc | 32 ++++++++++++++++++++++++++++++-- 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& 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::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 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 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 -- 2.7.4