1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map>
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/callback.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/compiler_specific.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/keyed_service/core/keyed_service_export.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DependencyNode;
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Dynamic graph of dependencies between nodes.
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class KEYED_SERVICE_EXPORT DependencyGraph {
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DependencyGraph();
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~DependencyGraph();
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Adds/Removes a node from our list of live nodes. Removing will
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // also remove live dependency links.
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AddNode(DependencyNode* node);
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RemoveNode(DependencyNode* node);
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Adds a dependency between two nodes.
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void AddEdge(DependencyNode* depended, DependencyNode* dependee);
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Topologically sorts nodes to produce a safe construction order
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // (all nodes after their dependees).
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool GetConstructionOrder(std::vector<DependencyNode*>* order)
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      WARN_UNUSED_RESULT;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Topologically sorts nodes to produce a safe destruction order
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // (all nodes before their dependees).
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool GetDestructionOrder(std::vector<DependencyNode*>* order)
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      WARN_UNUSED_RESULT;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns representation of the dependency graph in graphviz format.
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string DumpAsGraphviz(const std::string& toplevel_name,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                             const base::Callback<std::string(DependencyNode*)>&
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 node_name_callback) const;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef std::multimap<DependencyNode*, DependencyNode*> EdgeMap;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populates |construction_order_| with computed construction order.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true on success.
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool BuildConstructionOrder() WARN_UNUSED_RESULT;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Keeps track of all live nodes (see AddNode, RemoveNode).
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<DependencyNode*> all_nodes_;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Keeps track of edges of the dependency graph.
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EdgeMap edges_;
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Cached construction order (needs rebuild with BuildConstructionOrder
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // when empty).
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<DependencyNode*> construction_order_;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DependencyGraph);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_GRAPH_H_
68