java-topology/defects/ninja/patch/ninja-0001-depfile-unordered-set.patch

58 lines
2 KiB
Diff

# UNDF: UNDF-2026-000000186
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc
index abc1234..def5678 100644
--- a/src/depfile_parser.in.cc
+++ b/src/depfile_parser.in.cc
@@ -1,6 +1,7 @@
// Copyright 2011 Google Inc. All Rights Reserved.
#include "depfile_parser.h"
#include <algorithm>
+#include <unordered_set>
bool DepfileParser::Parse(string* content, string* err) {
// ...
@@ -170,14 +170,21 @@ bool DepfileParser::Parse(string* content, string* err) {
if (len > 0) {
is_empty = false;
StringPiece piece = StringPiece(filename, len);
- // If we've seen this as an input before, skip it.
- std::vector<StringPiece>::iterator pos = std::find(ins_.begin(), ins_.end(), piece);
- if (pos == ins_.end()) {
+ // Use a hash-set shadow to make membership check O(1) instead of
+ // O(n), avoiding O(n^2) total cost when a depfile has many entries.
+ if (ins_set_.find(piece) == ins_set_.end()) {
if (is_dependency) {
if (poisoned_input) {
*err = "inputs may not also have inputs";
return false;
}
- // New input.
- ins_.push_back(piece);
+ ins_set_.insert(piece);
+ ins_.push_back(piece);
} else {
// Check for a new output.
- if (std::find(outs_.begin(), outs_.end(), piece) == outs_.end())
+ if (outs_set_.insert(piece).second)
outs_.push_back(piece);
}
} else if (!is_dependency) {
diff --git a/src/depfile_parser.h b/src/depfile_parser.h
index abc1234..def5678 100644
--- a/src/depfile_parser.h
+++ b/src/depfile_parser.h
@@ -1,6 +1,7 @@
#pragma once
#include <string>
+#include <unordered_set>
#include <vector>
#include "string_piece.h"
struct DepfileParser {
std::vector<StringPiece> ins_;
std::vector<StringPiece> outs_;
+ // Shadow sets for O(1) duplicate detection.
+ std::unordered_set<StringPiece> ins_set_;
+ std::unordered_set<StringPiece> outs_set_;
};