7 #include "segmentgraph.h" 11 #include <unordered_set> 14 #include <boost/range/combine.hpp> 15 #include <boost/tuple/tuple.hpp> 24 return lhs.first->index() > rhs.first->index();
30 return lhs->index() > rhs->index();
35 const SegmentGraphBFSCallback &callback)
const {
37 std::vector<const SegmentGraphNode *>,
41 std::unordered_set<const SegmentGraphNode *> visited;
43 const auto *node = q.top();
45 if (!visited.contains(node)) {
51 if (!callback(*
this, node)) {
54 for (
const auto &next : node->nexts()) {
61 size_t SegmentGraph::check(
const SegmentGraph &graph)
const {
63 std::pair<const SegmentGraphNode *, const SegmentGraphNode *>,
65 std::pair<const SegmentGraphNode *, const SegmentGraphNode *>>,
69 q.emplace(&start(), &graph.start());
71 auto [old, now] = q.top();
74 assert(old->index() == now->index());
75 if (old->nextSize() != now->nextSize()) {
81 for (
auto t : boost::combine(old->nexts(), now->nexts())) {
82 nold = &boost::get<0>(t);
83 nnow = &boost::get<1>(t);
84 if (nold->index() != nnow->index() ||
85 segment(*old, *nold) != graph.segment(*now, *nnow)) {
90 for (
auto t : boost::combine(old->nexts(), now->nexts())) {
91 nold = &boost::get<0>(t);
92 nnow = &boost::get<1>(t);
93 q.emplace(nold, nnow);
98 return end().index() + 1;
102 const DiscardCallback &discardCallback) {
103 if (&graph ==
this) {
106 auto since = check(graph);
107 std::unordered_set<const SegmentGraphNode *> nodeToDiscard;
108 for (
size_t i = 0; i < since; i++) {
109 for (
auto &node : mutableNodes(i)) {
110 std::vector<SegmentGraphNode *> newNext;
111 for (
auto &next : node.mutableNexts()) {
113 if (next.index() >= since) {
114 n = graph.graph_[next.index()].get();
118 newNext.push_back(n);
120 while (node.nextSize()) {
121 node.removeEdge(node.mutableNexts().front());
123 for (
auto *n : newNext) {
127 graph.graph_[i].reset();
130 mutableData() = graph.data();
133 if (data().size() + 1 < graph_.size()) {
134 for (
size_t i = data().size() + 1; i < graph_.size(); i++) {
135 for (
const auto &node : nodes(i)) {
136 nodeToDiscard.insert(&node);
141 resize(data().size() + 1);
142 for (
size_t i = since; i <= size(); i++) {
143 for (
const auto &node : nodes(i)) {
144 nodeToDiscard.insert(&node);
146 std::swap(graph_[i], graph.graph_[i]);
147 graph.graph_[i].reset();
150 if (discardCallback) {
151 discardCallback(nodeToDiscard);