Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: tools/gn/command_path.cc

Issue 1143043004: Speed up "gn path". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/containers/hash_tables.h"
6 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
7 #include "tools/gn/commands.h" 8 #include "tools/gn/commands.h"
8 #include "tools/gn/setup.h" 9 #include "tools/gn/setup.h"
9 #include "tools/gn/standard_out.h" 10 #include "tools/gn/standard_out.h"
10 11
11 namespace commands { 12 namespace commands {
12 13
13 namespace { 14 namespace {
14 15
15 enum DepType { 16 enum DepType {
16 DEP_NONE, 17 DEP_NONE,
17 DEP_PUBLIC, 18 DEP_PUBLIC,
18 DEP_PRIVATE, 19 DEP_PRIVATE,
19 DEP_DATA 20 DEP_DATA
20 }; 21 };
21 22
22 // As we do a depth-first search, this vector will store the current path 23 // As we do a depth-first search, this vector will store the current path
23 // the current target for printing when a match is found. 24 // the current target for printing when a match is found.
24 using TargetDep = std::pair<const Target*, DepType>; 25 using TargetDep = std::pair<const Target*, DepType>;
25 using DepStack = std::vector<TargetDep>; 26 using DepStack = std::vector<TargetDep>;
26 27
28 using DepSet = base::hash_set<const Target*>;
29
27 void PrintDepStack(const DepStack& stack) { 30 void PrintDepStack(const DepStack& stack) {
28 // Don't print toolchains unless they differ from the first target. 31 // Don't print toolchains unless they differ from the first target.
29 const Label& default_toolchain = stack[0].first->label().GetToolchainLabel(); 32 const Label& default_toolchain = stack[0].first->label().GetToolchainLabel();
30 33
31 for (const auto& pair : stack) { 34 for (const auto& pair : stack) {
32 OutputString(pair.first->label().GetUserVisibleName(default_toolchain)); 35 OutputString(pair.first->label().GetUserVisibleName(default_toolchain));
33 switch (pair.second) { 36 switch (pair.second) {
34 case DEP_NONE: 37 case DEP_NONE:
35 break; 38 break;
36 case DEP_PUBLIC: 39 case DEP_PUBLIC:
37 OutputString(" --[public]-->", DECORATION_DIM); 40 OutputString(" --[public]-->", DECORATION_DIM);
38 break; 41 break;
39 case DEP_PRIVATE: 42 case DEP_PRIVATE:
40 OutputString(" --[private]-->", DECORATION_DIM); 43 OutputString(" --[private]-->", DECORATION_DIM);
41 break; 44 break;
42 case DEP_DATA: 45 case DEP_DATA:
43 OutputString(" --[data]-->", DECORATION_DIM); 46 OutputString(" --[data]-->", DECORATION_DIM);
44 break; 47 break;
45 } 48 }
46 OutputString("\n"); 49 OutputString("\n");
47 } 50 }
48 OutputString("\n"); 51 OutputString("\n");
49 } 52 }
50 53
51 // Increments *found_count to reflect how many results are found. If print_all 54 // Increments *found_count to reflect how many results are found. If print_all
52 // is not set, only the first result will be printed. 55 // is not set, only the first result will be printed.
56 //
57 // As an optimization, targets that do not have any paths are added to
58 // *reject so this function doesn't waste time revisiting them.
53 void RecursiveFindPath(const Target* current, 59 void RecursiveFindPath(const Target* current,
54 const Target* desired, 60 const Target* desired,
55 DepStack* stack, 61 DepStack* stack,
62 DepSet* reject,
56 int* found_count, 63 int* found_count,
57 bool print_all) { 64 bool print_all) {
65 if (reject->find(current) != reject->end())
66 return;
67 int initial_found_count = *found_count;
68
58 if (current == desired) { 69 if (current == desired) {
59 (*found_count)++; 70 (*found_count)++;
60 if (print_all || *found_count == 1) { 71 if (print_all || *found_count == 1) {
61 stack->push_back(TargetDep(current, DEP_NONE)); 72 stack->push_back(TargetDep(current, DEP_NONE));
62 PrintDepStack(*stack); 73 PrintDepStack(*stack);
63 stack->pop_back(); 74 stack->pop_back();
64 } 75 }
65 return; 76 return;
66 } 77 }
67 78
68 stack->push_back(TargetDep(current, DEP_PUBLIC)); 79 stack->push_back(TargetDep(current, DEP_PUBLIC));
69 for (const auto& pair : current->public_deps()) 80 for (const auto& pair : current->public_deps())
70 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all); 81 RecursiveFindPath(pair.ptr, desired, stack, reject, found_count, print_all);
71 82
72 stack->back().second = DEP_PRIVATE; 83 stack->back().second = DEP_PRIVATE;
73 for (const auto& pair : current->private_deps()) 84 for (const auto& pair : current->private_deps())
74 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all); 85 RecursiveFindPath(pair.ptr, desired, stack, reject, found_count, print_all);
75 86
76 stack->back().second = DEP_DATA; 87 stack->back().second = DEP_DATA;
77 for (const auto& pair : current->data_deps()) 88 for (const auto& pair : current->data_deps())
78 RecursiveFindPath(pair.ptr, desired, stack, found_count, print_all); 89 RecursiveFindPath(pair.ptr, desired, stack, reject, found_count, print_all);
79 stack->pop_back(); 90 stack->pop_back();
91
92 if (*found_count == initial_found_count)
93 reject->insert(current); // Eliminated this target.
80 } 94 }
81 95
82 } // namespace 96 } // namespace
83 97
84 const char kPath[] = "path"; 98 const char kPath[] = "path";
85 const char kPath_HelpShort[] = 99 const char kPath_HelpShort[] =
86 "path: Find paths between two targets."; 100 "path: Find paths between two targets.";
87 const char kPath_Help[] = 101 const char kPath_Help[] =
88 "gn path <out_dir> <target_one> <target_two>\n" 102 "gn path <out_dir> <target_one> <target_two>\n"
89 "\n" 103 "\n"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 const Target* target2 = ResolveTargetFromCommandLineString(setup, args[2]); 139 const Target* target2 = ResolveTargetFromCommandLineString(setup, args[2]);
126 if (!target2) 140 if (!target2)
127 return 1; 141 return 1;
128 142
129 bool print_all = base::CommandLine::ForCurrentProcess()->HasSwitch("all"); 143 bool print_all = base::CommandLine::ForCurrentProcess()->HasSwitch("all");
130 144
131 // If we don't find a path going "forwards", try the reverse direction. Deps 145 // If we don't find a path going "forwards", try the reverse direction. Deps
132 // can only go in one direction without having a cycle, which will have 146 // can only go in one direction without having a cycle, which will have
133 // caused a run failure above. 147 // caused a run failure above.
134 DepStack stack; 148 DepStack stack;
149 DepSet rejected;
135 int found = 0; 150 int found = 0;
136 RecursiveFindPath(target1, target2, &stack, &found, print_all); 151 RecursiveFindPath(target1, target2, &stack, &rejected, &found, print_all);
137 if (found == 0) 152 if (found == 0) {
138 RecursiveFindPath(target2, target1, &stack, &found, print_all); 153 // Need to reset the rejected set for a new invocation since the reverse
154 // search will revisit the same targets looking for something else.
155 rejected.clear();
156 RecursiveFindPath(target2, target1, &stack, &rejected, &found, print_all);
157 }
139 158
140 if (found == 0) { 159 if (found == 0) {
141 OutputString("No paths found between these two targets.\n", 160 OutputString("No paths found between these two targets.\n",
142 DECORATION_YELLOW); 161 DECORATION_YELLOW);
143 } else if (found == 1) { 162 } else if (found == 1) {
144 OutputString("1 path found.\n", DECORATION_YELLOW); 163 OutputString("1 path found.\n", DECORATION_YELLOW);
145 } else { 164 } else {
146 if (print_all) { 165 if (print_all) {
147 OutputString(base::StringPrintf("%d unique paths found.\n", found), 166 OutputString(base::StringPrintf("%d unique paths found.\n", found),
148 DECORATION_YELLOW); 167 DECORATION_YELLOW);
149 } else { 168 } else {
150 OutputString( 169 OutputString(
151 base::StringPrintf("Showing the first of %d unique paths. ", found), 170 base::StringPrintf("Showing the first of %d unique paths. ", found),
152 DECORATION_YELLOW); 171 DECORATION_YELLOW);
153 OutputString("Use --all to print all paths.\n"); 172 OutputString("Use --all to print all paths.\n");
154 } 173 }
155 } 174 }
156 return 0; 175 return 0;
157 } 176 }
158 177
159 } // namespace commands 178 } // namespace commands
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698