Ninja
state.cc
Go to the documentation of this file.
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "state.h"
16 
17 #include <assert.h>
18 #include <stdio.h>
19 
20 #include "edit_distance.h"
21 #include "graph.h"
22 #include "metrics.h"
23 #include "util.h"
24 
25 
26 void Pool::EdgeScheduled(const Edge& edge) {
27  if (depth_ != 0)
28  current_use_ += edge.weight();
29 }
30 
31 void Pool::EdgeFinished(const Edge& edge) {
32  if (depth_ != 0)
33  current_use_ -= edge.weight();
34 }
35 
36 void Pool::DelayEdge(Edge* edge) {
37  assert(depth_ != 0);
38  delayed_.insert(edge);
39 }
40 
41 void Pool::RetrieveReadyEdges(set<Edge*>* ready_queue) {
42  DelayedEdges::iterator it = delayed_.begin();
43  while (it != delayed_.end()) {
44  Edge* edge = *it;
45  if (current_use_ + edge->weight() > depth_)
46  break;
47  ready_queue->insert(edge);
48  EdgeScheduled(*edge);
49  ++it;
50  }
51  delayed_.erase(delayed_.begin(), it);
52 }
53 
54 void Pool::Dump() const {
55  printf("%s (%d/%d) ->\n", name_.c_str(), current_use_, depth_);
56  for (DelayedEdges::const_iterator it = delayed_.begin();
57  it != delayed_.end(); ++it)
58  {
59  printf("\t");
60  (*it)->Dump();
61  }
62 }
63 
64 bool Pool::WeightedEdgeCmp(const Edge* a, const Edge* b) {
65  if (!a) return b;
66  if (!b) return false;
67  int weight_diff = a->weight() - b->weight();
68  return ((weight_diff < 0) || (weight_diff == 0 && a < b));
69 }
70 
72 Pool State::kConsolePool("console", 1);
73 const Rule State::kPhonyRule("phony");
74 
79 }
80 
81 void State::AddRule(const Rule* rule) {
82  assert(LookupRule(rule->name()) == NULL);
83  rules_[rule->name()] = rule;
84 }
85 
86 const Rule* State::LookupRule(const string& rule_name) {
87  map<string, const Rule*>::iterator i = rules_.find(rule_name);
88  if (i == rules_.end())
89  return NULL;
90  return i->second;
91 }
92 
93 void State::AddPool(Pool* pool) {
94  assert(LookupPool(pool->name()) == NULL);
95  pools_[pool->name()] = pool;
96 }
97 
98 Pool* State::LookupPool(const string& pool_name) {
99  map<string, Pool*>::iterator i = pools_.find(pool_name);
100  if (i == pools_.end())
101  return NULL;
102  return i->second;
103 }
104 
105 Edge* State::AddEdge(const Rule* rule) {
106  Edge* edge = new Edge();
107  edge->rule_ = rule;
108  edge->pool_ = &State::kDefaultPool;
109  edge->env_ = &bindings_;
110  edges_.push_back(edge);
111  return edge;
112 }
113 
114 Node* State::GetNode(StringPiece path, unsigned int slash_bits) {
115  Node* node = LookupNode(path);
116  if (node)
117  return node;
118  node = new Node(path.AsString(), slash_bits);
119  paths_[node->path()] = node;
120  return node;
121 }
122 
124  METRIC_RECORD("lookup node");
125  Paths::const_iterator i = paths_.find(path);
126  if (i != paths_.end())
127  return i->second;
128  return NULL;
129 }
130 
131 Node* State::SpellcheckNode(const string& path) {
132  const bool kAllowReplacements = true;
133  const int kMaxValidEditDistance = 3;
134 
135  int min_distance = kMaxValidEditDistance + 1;
136  Node* result = NULL;
137  for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i) {
138  int distance = EditDistance(
139  i->first, path, kAllowReplacements, kMaxValidEditDistance);
140  if (distance < min_distance && i->second) {
141  min_distance = distance;
142  result = i->second;
143  }
144  }
145  return result;
146 }
147 
148 void State::AddIn(Edge* edge, StringPiece path, unsigned int slash_bits) {
149  Node* node = GetNode(path, slash_bits);
150  edge->inputs_.push_back(node);
151  node->AddOutEdge(edge);
152 }
153 
154 void State::AddOut(Edge* edge, StringPiece path, unsigned int slash_bits) {
155  Node* node = GetNode(path, slash_bits);
156  edge->outputs_.push_back(node);
157  if (node->in_edge()) {
158  Warning("multiple rules generate %s. "
159  "builds involving this target will not be correct; "
160  "continuing anyway",
161  path.AsString().c_str());
162  }
163  node->set_in_edge(edge);
164 }
165 
166 bool State::AddDefault(StringPiece path, string* err) {
167  Node* node = LookupNode(path);
168  if (!node) {
169  *err = "unknown target '" + path.AsString() + "'";
170  return false;
171  }
172  defaults_.push_back(node);
173  return true;
174 }
175 
176 vector<Node*> State::RootNodes(string* err) {
177  vector<Node*> root_nodes;
178  // Search for nodes with no output.
179  for (vector<Edge*>::iterator e = edges_.begin(); e != edges_.end(); ++e) {
180  for (vector<Node*>::iterator out = (*e)->outputs_.begin();
181  out != (*e)->outputs_.end(); ++out) {
182  if ((*out)->out_edges().empty())
183  root_nodes.push_back(*out);
184  }
185  }
186 
187  if (!edges_.empty() && root_nodes.empty())
188  *err = "could not determine root nodes of build graph";
189 
190  assert(edges_.empty() || !root_nodes.empty());
191  return root_nodes;
192 }
193 
194 vector<Node*> State::DefaultNodes(string* err) {
195  return defaults_.empty() ? RootNodes(err) : defaults_;
196 }
197 
198 void State::Reset() {
199  for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i)
200  i->second->ResetState();
201  for (vector<Edge*>::iterator e = edges_.begin(); e != edges_.end(); ++e)
202  (*e)->outputs_ready_ = false;
203 }
204 
205 void State::Dump() {
206  for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i) {
207  Node* node = i->second;
208  printf("%s %s [id:%d]\n",
209  node->path().c_str(),
210  node->status_known() ? (node->dirty() ? "dirty" : "clean")
211  : "unknown",
212  node->id());
213  }
214  if (!pools_.empty()) {
215  printf("resource_pools:\n");
216  for (map<string, Pool*>::const_iterator it = pools_.begin();
217  it != pools_.end(); ++it)
218  {
219  if (!it->second->name().empty()) {
220  it->second->Dump();
221  }
222  }
223  }
224 }
void Reset()
Reset state.
Definition: state.cc:198
vector< Edge * > edges_
All the edges of the graph.
Definition: state.h:129
void EdgeScheduled(const Edge &edge)
informs this Pool that the given edge is committed to be run.
Definition: state.cc:26
Pool * LookupPool(const string &pool_name)
Definition: state.cc:98
StringPiece represents a slice of a string whose memory is managed externally.
Definition: string_piece.h:27
Paths paths_
Definition: state.h:120
Information about a node in the dependency graph: the file, whether it's dirty, mtime, etc.
Definition: graph.h:35
Node * SpellcheckNode(const string &path)
Definition: state.cc:131
vector< Node * > defaults_
Definition: state.h:132
Edge * in_edge() const
Definition: graph.h:84
string AsString() const
Convert the slice into a full-fledged std::string, copying the data into a new string.
Definition: string_piece.h:45
void AddOutEdge(Edge *edge)
Definition: graph.h:91
Node * GetNode(StringPiece path, unsigned int slash_bits)
Definition: state.cc:114
An edge in the dependency graph; links between Nodes using Rules.
Definition: graph.h:146
DelayedEdges delayed_
Definition: state.h:79
Edge * AddEdge(const Rule *rule)
Definition: state.cc:105
vector< Node * > inputs_
Definition: graph.h:171
State()
Definition: state.cc:75
vector< Node * > DefaultNodes(string *error)
Definition: state.cc:194
void Dump()
Dump the nodes and Pools (useful for debugging).
Definition: state.cc:205
void AddRule(const Rule *rule)
Definition: state.cc:81
BindingEnv * env_
Definition: graph.h:173
An invokable build command and associated metadata (description, etc.).
Definition: graph.h:125
bool dirty() const
Definition: graph.h:80
bool status_known() const
Definition: graph.h:70
static Pool kConsolePool
Definition: state.h:85
void DelayEdge(Edge *edge)
adds the given edge to this Pool to be delayed.
Definition: state.cc:36
A pool for delayed edges.
Definition: state.h:39
void AddPool(Pool *pool)
Definition: state.cc:93
vector< Node * > RootNodes(string *error)
Definition: state.cc:176
#define METRIC_RECORD(name)
The primary interface to metrics.
Definition: metrics.h:85
BindingEnv bindings_
Definition: state.h:131
const string & name() const
Definition: state.h:46
const string & path() const
Definition: graph.h:74
void RetrieveReadyEdges(set< Edge * > *ready_queue)
Pool will add zero or more edges to the ready_queue.
Definition: state.cc:41
int id() const
Definition: graph.h:87
Pool * pool_
Definition: graph.h:170
bool AddDefault(StringPiece path, string *error)
Definition: state.cc:166
const Rule * rule_
Definition: graph.h:169
static bool WeightedEdgeCmp(const Edge *a, const Edge *b)
Definition: state.cc:64
string name_
Definition: state.h:69
void EdgeFinished(const Edge &edge)
informs this Pool that the given edge is no longer runnable, and should relinquish its resources back...
Definition: state.cc:31
void AddOut(Edge *edge, StringPiece path, unsigned int slash_bits)
Definition: state.cc:154
void set_in_edge(Edge *edge)
Definition: graph.h:85
const string & name() const
Definition: graph.h:128
void Dump() const
Dump the Pool and its edges (useful for debugging).
Definition: state.cc:54
void AddIn(Edge *edge, StringPiece path, unsigned int slash_bits)
Definition: state.cc:148
int weight() const
Definition: graph.h:179
map< string, Pool * > pools_
All the pools used in the graph.
Definition: state.h:126
void Warning(const char *msg,...)
Log a warning message.
Definition: util.cc:70
static Pool kDefaultPool
Definition: state.h:84
int EditDistance(const StringPiece &s1, const StringPiece &s2, bool allow_replacements, int max_edit_distance)
map< string, const Rule * > rules_
All the rules used in the graph.
Definition: state.h:123
const Rule * LookupRule(const string &rule_name)
Definition: state.cc:86
int current_use_
|current_use_| is the total of the weights of the edges which are currently scheduled in the Plan (i...
Definition: state.h:73
int depth_
Definition: state.h:74
static const Rule kPhonyRule
Definition: state.h:86
Node * LookupNode(StringPiece path) const
Definition: state.cc:123
vector< Node * > outputs_
Definition: graph.h:172