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

Side by Side Diff: chrome/browser/profiles/dependency_graph.cc

Issue 13454032: Extract DependencyGraph from ProfileDependencyManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/profiles/dependency_graph.h"
6
7 #include <algorithm>
8 #include <deque>
9 #include <iterator>
10
11 DependencyGraph::DependencyGraph(const GetNodeNameCallback& callback)
12 : get_node_name_callback_(callback) {
13 }
14
15 DependencyGraph::~DependencyGraph() {
16 }
17
18 void DependencyGraph::AddNode(void* node) {
19 all_nodes_.push_back(node);
20 construction_order_.clear();
21 }
22
23 void DependencyGraph::RemoveNode(void* node) {
24 all_nodes_.erase(std::remove(all_nodes_.begin(),
25 all_nodes_.end(),
26 node),
27 all_nodes_.end());
28
29 // Remove all dependency edges that contain this node.
30 EdgeMap::iterator it = edges_.begin();
31 while (it != edges_.end()) {
32 EdgeMap::iterator temp = it;
33 ++it;
34
35 if (temp->first == node || temp->second == node)
36 edges_.erase(temp);
37 }
38
39 construction_order_.clear();
40 }
41
42 void DependencyGraph::AddEdge(void* depended, void* dependee) {
43 edges_.insert(std::make_pair(depended, dependee));
44 construction_order_.clear();
45 }
46
47 bool DependencyGraph::GetConstructionOrder(std::vector<void*>* order) {
48 if (construction_order_.empty() && !BuildConstructionOrder())
49 return false;
50
51 *order = construction_order_;
52 return true;
53 }
54
55 bool DependencyGraph::GetDestructionOrder(std::vector<void*>* order) {
56 if (construction_order_.empty() && !BuildConstructionOrder())
57 return false;
58
59 *order = construction_order_;
60
61 // Destroy nodes in reverse order.
62 std::reverse(order->begin(), order->end());
63
64 return true;
65 }
66
67 bool DependencyGraph::BuildConstructionOrder() {
68 // Step 1: Build a set of nodes with no incoming edges.
69 std::deque<void*> queue;
70 std::copy(all_nodes_.begin(),
71 all_nodes_.end(),
72 std::back_inserter(queue));
73
74 std::deque<void*>::iterator queue_end = queue.end();
75 for (EdgeMap::const_iterator it = edges_.begin();
76 it != edges_.end(); ++it) {
77 queue_end = std::remove(queue.begin(), queue_end, it->second);
78 }
79 queue.erase(queue_end, queue.end());
80
81 // Step 2: Do the Kahn topological sort.
82 std::vector<void*> output;
83 EdgeMap edges(edges_);
84 while (!queue.empty()) {
85 void* node = queue.front();
86 queue.pop_front();
87 output.push_back(node);
88
89 std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
90 edges.equal_range(node);
91 EdgeMap::iterator it = range.first;
92 while (it != range.second) {
93 void* dest = it->second;
94 EdgeMap::iterator temp = it;
95 it++;
96 edges.erase(temp);
97
98 bool has_incoming_edges = false;
99 for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
100 if (jt->second == dest) {
101 has_incoming_edges = true;
102 break;
103 }
104 }
105
106 if (!has_incoming_edges)
107 queue.push_back(dest);
108 }
109 }
110
111 if (!edges.empty()) {
112 // Dependency graph has a cycle.
113 return false;
114 }
115
116 construction_order_ = output;
117 return true;
118 }
119
120 std::string DependencyGraph::DumpAsGraphviz(const std::string& toplevel_name) {
121 std::string result("digraph {\n");
122
123 // Make a copy of all nodes.
124 std::deque<void*> nodes;
125 std::copy(all_nodes_.begin(), all_nodes_.end(), std::back_inserter(nodes));
126
127 // State all dependencies and remove |second| so we don't generate an
128 // implicit dependency on the top level node.
129 std::deque<void*>::iterator nodes_end(nodes.end());
130 result.append(" /* Dependencies */\n");
131 for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
132 result.append(" ");
133 result.append(get_node_name_callback_.Run(it->second));
134 result.append(" -> ");
135 result.append(get_node_name_callback_.Run(it->first));
136 result.append(";\n");
137
138 nodes_end = std::remove(nodes.begin(), nodes_end, it->second);
139 }
140 nodes.erase(nodes_end, nodes.end());
141
142 // Every node that doesn't depend on anything else will implicitly depend on
143 // the top level node.
144 result.append("\n /* Toplevel attachments */\n");
145 for (std::deque<void*>::const_iterator it =
146 nodes.begin(); it != nodes.end(); ++it) {
147 result.append(" ");
148 result.append(get_node_name_callback_.Run(*it));
149 result.append(" -> ");
150 result.append(toplevel_name);
151 result.append(";\n");
152 }
153
154 result.append("\n /* Toplevel node */\n");
155 result.append(" ");
156 result.append(toplevel_name);
157 result.append(" [shape=box];\n");
158
159 result.append("}\n");
160 return result;
161 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698