@@ -37,6 +37,12 @@ DepsLog::~DepsLog() {
37
37
}
38
38
39
39
bool DepsLog::OpenForWrite (const string& path, string* err) {
40
+ if (needs_recompaction_) {
41
+ Close ();
42
+ if (!Recompact (path, err))
43
+ return false ;
44
+ }
45
+
40
46
file_ = fopen (path.c_str (), " ab" );
41
47
if (!file_) {
42
48
*err = strerror (errno);
@@ -161,6 +167,8 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
161
167
162
168
long offset;
163
169
bool read_failed = false ;
170
+ int unique_dep_record_count = 0 ;
171
+ int total_dep_record_count = 0 ;
164
172
for (;;) {
165
173
offset = ftell (f);
166
174
@@ -193,8 +201,9 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
193
201
deps->nodes [i] = nodes_[deps_data[i]];
194
202
}
195
203
196
- if (UpdateDeps (out_id, deps))
197
- ++dead_record_count_;
204
+ total_dep_record_count++;
205
+ if (!UpdateDeps (out_id, deps))
206
+ ++unique_dep_record_count;
198
207
} else {
199
208
StringPiece path (buf, size);
200
209
Node* node = state->GetNode (path);
@@ -225,6 +234,14 @@ bool DepsLog::Load(const string& path, State* state, string* err) {
225
234
226
235
fclose (f);
227
236
237
+ // Rebuild the log if there are too many dead records.
238
+ int kMinCompactionEntryCount = 1000 ;
239
+ int kCompactionRatio = 3 ;
240
+ if (total_dep_record_count > kMinCompactionEntryCount &&
241
+ total_dep_record_count > unique_dep_record_count * kCompactionRatio ) {
242
+ needs_recompaction_ = true ;
243
+ }
244
+
228
245
return true ;
229
246
}
230
247
0 commit comments