proxygen
GraphCycleDetector.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <unordered_map>
19 #include <unordered_set>
20 
21 #include <glog/logging.h>
22 
23 namespace folly {
24 namespace observer_detail {
25 
26 template <typename NodeId>
28  using NodeSet = std::unordered_set<NodeId>;
29 
30  public:
35  bool addEdge(NodeId from, NodeId to) {
36  // In general case DFS may be expensive here, but in most cases to-node will
37  // have no edges, so it should be O(1).
38  NodeSet visitedNodes;
39  dfs(visitedNodes, to);
40  if (visitedNodes.count(from)) {
41  return false;
42  }
43 
44  auto& nodes = edges_[from];
45  DCHECK_EQ(nodes.count(to), 0u);
46  nodes.insert(to);
47 
48  return true;
49  }
50 
51  void removeEdge(NodeId from, NodeId to) {
52  auto& nodes = edges_[from];
53  DCHECK(nodes.count(to));
54  nodes.erase(to);
55  if (nodes.empty()) {
56  edges_.erase(from);
57  }
58  }
59 
60  private:
61  void dfs(NodeSet& visitedNodes, NodeId node) {
62  // We don't terminate early if cycle is detected, because this is considered
63  // an error condition, so not worth optimizing for.
64  if (visitedNodes.count(node)) {
65  return;
66  }
67 
68  visitedNodes.insert(node);
69 
70  if (!edges_.count(node)) {
71  return;
72  }
73 
74  for (const auto& to : edges_[node]) {
75  dfs(visitedNodes, to);
76  }
77  }
78 
79  std::unordered_map<NodeId, NodeSet> edges_;
80 };
81 } // namespace observer_detail
82 } // namespace folly
void dfs(NodeSet &visitedNodes, NodeId node)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::unordered_map< NodeId, NodeSet > edges_
std::enable_if< detail::is_chrono_conversion< Tgt, Src >::value, Tgt >::type to(const Src &value)
Definition: Conv.h:677
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::from_fn from