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 "util.h"
23
24using namespace std;
25
26void Pool::EdgeScheduled(const Edge& edge) {
27 if (depth_ != 0)
28 current_use_ += edge.weight();
29}
30
31void Pool::EdgeFinished(const Edge& edge) {
32 if (depth_ != 0)
33 current_use_ -= edge.weight();
34}
35
36void Pool::DelayEdge(Edge* edge) {
37 assert(depth_ != 0);
38 delayed_.insert(edge);
39}
40
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->push(edge);
48 EdgeScheduled(*edge);
49 ++it;
50 }
51 delayed_.erase(delayed_.begin(), it);
52}
53
54void 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
65Pool State::kConsolePool("console", 1);
66
72
73void State::AddPool(Pool* pool) {
74 assert(LookupPool(pool->name()) == NULL);
75 pools_[pool->name()] = pool;
76}
77
78Pool* State::LookupPool(const string& pool_name) {
79 map<string, Pool*>::iterator i = pools_.find(pool_name);
80 if (i == pools_.end())
81 return NULL;
82 return i->second;
83}
84
85Edge* State::AddEdge(const Rule* rule) {
86 Edge* edge = new Edge();
87 edge->rule_ = rule;
89 edge->env_ = &bindings_;
90 edge->id_ = edges_.size();
91 edges_.push_back(edge);
92 return edge;
93}
94
96 Node* node = LookupNode(path);
97 if (node)
98 return node;
99 node = new Node(path.AsString(), slash_bits);
100 paths_[node->path()] = node;
101 return node;
102}
103
105 Paths::const_iterator i = paths_.find(path);
106 if (i != paths_.end())
107 return i->second;
108 return NULL;
109}
110
111Node* State::SpellcheckNode(const string& path) {
112 const bool kAllowReplacements = true;
113 const int kMaxValidEditDistance = 3;
114
115 int min_distance = kMaxValidEditDistance + 1;
116 Node* result = NULL;
117 for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i) {
118 int distance = EditDistance(
119 i->first, path, kAllowReplacements, kMaxValidEditDistance);
120 if (distance < min_distance && i->second) {
121 min_distance = distance;
122 result = i->second;
123 }
124 }
125 return result;
126}
127
128void State::AddIn(Edge* edge, StringPiece path, uint64_t slash_bits) {
129 Node* node = GetNode(path, slash_bits);
130 node->set_generated_by_dep_loader(false);
131 edge->inputs_.push_back(node);
132 node->AddOutEdge(edge);
133}
134
135bool State::AddOut(Edge* edge, StringPiece path, uint64_t slash_bits,
136 std::string* err) {
137 Node* node = GetNode(path, slash_bits);
138 if (Edge* other = node->in_edge()) {
139 if (other == edge) {
140 *err = path.AsString() + " is defined as an output multiple times";
141 } else {
142 *err = "multiple rules generate " + path.AsString();
143 }
144 return false;
145 }
146 edge->outputs_.push_back(node);
147 node->set_in_edge(edge);
148 node->set_generated_by_dep_loader(false);
149 return true;
150}
151
152void State::AddValidation(Edge* edge, StringPiece path, uint64_t slash_bits) {
153 Node* node = GetNode(path, slash_bits);
154 edge->validations_.push_back(node);
155 node->AddValidationOutEdge(edge);
156 node->set_generated_by_dep_loader(false);
157}
158
159bool State::AddDefault(StringPiece path, string* err) {
160 Node* node = LookupNode(path);
161 if (!node) {
162 *err = "unknown target '" + path.AsString() + "'";
163 return false;
164 }
165 defaults_.push_back(node);
166 return true;
167}
168
169vector<Node*> State::RootNodes(string* err) const {
170 vector<Node*> root_nodes;
171 // Search for nodes with no output.
172 for (vector<Edge*>::const_iterator e = edges_.begin();
173 e != edges_.end(); ++e) {
174 for (vector<Node*>::const_iterator out = (*e)->outputs_.begin();
175 out != (*e)->outputs_.end(); ++out) {
176 if ((*out)->out_edges().empty())
177 root_nodes.push_back(*out);
178 }
179 }
180
181 if (!edges_.empty() && root_nodes.empty())
182 *err = "could not determine root nodes of build graph";
183
184 return root_nodes;
185}
186
187vector<Node*> State::DefaultNodes(string* err) const {
188 return defaults_.empty() ? RootNodes(err) : defaults_;
189}
190
192 for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i)
193 i->second->ResetState();
194 for (vector<Edge*>::iterator e = edges_.begin(); e != edges_.end(); ++e) {
195 (*e)->outputs_ready_ = false;
196 (*e)->deps_loaded_ = false;
197 (*e)->mark_ = Edge::VisitNone;
198 }
199}
200
202 for (Paths::iterator i = paths_.begin(); i != paths_.end(); ++i) {
203 Node* node = i->second;
204 printf("%s %s [id:%d]\n",
205 node->path().c_str(),
206 node->status_known() ? (node->dirty() ? "dirty" : "clean")
207 : "unknown",
208 node->id());
209 }
210 if (!pools_.empty()) {
211 printf("resource_pools:\n");
212 for (map<string, Pool*>::const_iterator it = pools_.begin();
213 it != pools_.end(); ++it)
214 {
215 if (!it->second->name().empty()) {
216 it->second->Dump();
217 }
218 }
219 }
220}
int EditDistance(const StringPiece &s1, const StringPiece &s2, bool allow_replacements, int max_edit_distance)
Definition hash_map.h:26
An edge in the dependency graph; links between Nodes using Rules.
Definition graph.h:175
std::vector< Node * > outputs_
Definition graph.h:217
int weight() const
Definition graph.h:232
const Rule * rule_
Definition graph.h:214
@ VisitNone
Definition graph.h:177
Pool * pool_
Definition graph.h:215
std::vector< Node * > validations_
Definition graph.h:218
BindingEnv * env_
Definition graph.h:220
std::vector< Node * > inputs_
Definition graph.h:216
size_t id_
Definition graph.h:222
Information about a node in the dependency graph: the file, whether it's dirty, mtime,...
Definition graph.h:42
const std::string & path() const
Definition graph.h:82
void set_in_edge(Edge *edge)
Definition graph.h:101
int id() const
Definition graph.h:111
Edge * in_edge() const
Definition graph.h:100
void AddValidationOutEdge(Edge *edge)
Definition graph.h:117
bool dirty() const
Definition graph.h:93
void AddOutEdge(Edge *edge)
Definition graph.h:116
bool status_known() const
Definition graph.h:78
void set_generated_by_dep_loader(bool value)
Definition graph.h:107
A pool for delayed edges.
Definition state.h:40
int depth_
Definition state.h:76
DelayedEdges delayed_
Definition state.h:91
void DelayEdge(Edge *edge)
adds the given edge to this Pool to be delayed.
Definition state.cc:36
void RetrieveReadyEdges(EdgePriorityQueue *ready_queue)
Pool will add zero or more edges to the ready_queue.
Definition state.cc:41
void EdgeScheduled(const Edge &edge)
informs this Pool that the given edge is committed to be run.
Definition state.cc:26
const std::string & name() const
Definition state.h:47
std::string name_
Definition state.h:71
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
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:75
void Dump() const
Dump the Pool and its edges (useful for debugging).
Definition state.cc:54
An invocable build command and associated metadata (description, etc.).
Definition eval_env.h:66
static std::unique_ptr< Rule > Phony()
Definition eval_env.cc:66
std::vector< Node * > RootNodes(std::string *error) const
Definition state.cc:169
void AddValidation(Edge *edge, StringPiece path, uint64_t slash_bits)
Definition state.cc:152
std::vector< Edge * > edges_
All the edges of the graph.
Definition state.h:138
static Pool kConsolePool
Definition state.h:97
std::vector< Node * > DefaultNodes(std::string *error) const
Definition state.cc:187
bool AddDefault(StringPiece path, std::string *error)
Definition state.cc:159
void AddPool(Pool *pool)
Definition state.cc:73
Edge * AddEdge(const Rule *rule)
Definition state.cc:85
Node * SpellcheckNode(const std::string &path)
Definition state.cc:111
Paths paths_
Definition state.h:132
Node * GetNode(StringPiece path, uint64_t slash_bits)
Definition state.cc:95
static Pool kDefaultPool
Definition state.h:96
void AddIn(Edge *edge, StringPiece path, uint64_t slash_bits)
Add input / output / validation nodes to a given edge.
Definition state.cc:128
Node * LookupNode(StringPiece path) const
Definition state.cc:104
State()
Definition state.cc:67
BindingEnv bindings_
Definition state.h:140
std::map< std::string, Pool * > pools_
All the pools used in the graph.
Definition state.h:135
Pool * LookupPool(const std::string &pool_name)
Definition state.cc:78
void Reset()
Reset state.
Definition state.cc:191
std::vector< Node * > defaults_
Definition state.h:141
void Dump()
Dump the nodes and Pools (useful for debugging).
Definition state.cc:201
bool AddOut(Edge *edge, StringPiece path, uint64_t slash_bits, std::string *err)
Definition state.cc:135
StringPiece represents a slice of a string whose memory is managed externally.
std::string AsString() const
Convert the slice into a full-fledged std::string, copying the data into a new string.
unsigned long long uint64_t
Definition win32port.h:29