github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/runtime/nr/graph/graph.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #include "runtime/nr/graph/graph.h" 21 #include <boost/graph/graphviz.hpp> 22 #include <map> 23 24 namespace neb { 25 namespace rt { 26 27 transaction_graph::transaction_graph() : m_cur_max_index(0), m_edge_index(0) {} 28 29 void transaction_graph::add_edge(const address_t &from, const address_t &to, 30 wei_t val, int64_t ts) { 31 uint64_t from_vertex, to_vertex; 32 33 auto tmp_func = [&](const address_t &addr) { 34 uint64_t ret; 35 if (m_addr_to_vertex.find(addr) != m_addr_to_vertex.end()) { 36 ret = m_addr_to_vertex[addr]; 37 } else { 38 ret = m_cur_max_index; 39 m_cur_max_index++; 40 m_vertex_to_addr.insert(std::make_pair(ret, addr)); 41 m_addr_to_vertex.insert(std::make_pair(addr, ret)); 42 } 43 return ret; 44 }; 45 46 from_vertex = tmp_func(from); 47 to_vertex = tmp_func(to); 48 49 // boost::add_edge(from_vertex, to_vertex, {val, ts, m_edge_index}, m_graph); 50 edge_property_t prop; 51 boost::get_property_value(prop, boost::edge_weight) = val; 52 boost::get_property_value(prop, boost::edge_timestamp) = ts; 53 boost::get_property_value(prop, boost::edge_sort_id) = m_edge_index; 54 boost::add_edge(from_vertex, to_vertex, prop, m_graph); 55 m_edge_index++; 56 57 boost::put(boost::vertex_name_t(), m_graph, from_vertex, 58 std::to_string(from)); 59 boost::put(boost::vertex_name_t(), m_graph, to_vertex, std::to_string(to)); 60 } 61 62 void transaction_graph::write_to_graphviz(const std::string &filename) { 63 std::map<std::string, std::string> graph_attr, vertex_attr, edge_attr; 64 65 std::ofstream of; 66 of.open(filename); 67 boost::dynamic_properties dp; 68 dp.property("node_id", boost::get(boost::vertex_name, m_graph)); 69 70 boost::write_graphviz( 71 of, m_graph, 72 boost::make_label_writer(boost::get(boost::vertex_name, m_graph)), 73 boost::make_label_writer(boost::get(boost::edge_weight, m_graph)), 74 boost::make_graph_attributes_writer(graph_attr, vertex_attr, edge_attr)); 75 76 of.close(); 77 } 78 79 bool transaction_graph::read_from_graphviz(const std::string &filename) { 80 std::ifstream ifs(filename); 81 if (!ifs) { 82 return false; 83 } 84 85 std::stringstream ss; 86 ss << ifs.rdbuf(); 87 ifs.close(); 88 89 boost::dynamic_properties dp(boost::ignore_other_properties); 90 dp.property("label", boost::get(boost::vertex_name, m_graph)); 91 dp.property("label", boost::get(boost::edge_weight, m_graph)); 92 return boost::read_graphviz(ss, m_graph, dp); 93 } 94 95 transaction_graph_ptr_t build_graph_from_internal( 96 const transaction_graph::internal_graph_t &internal_graph) { 97 98 transaction_graph_ptr_t tg_ptr = std::make_unique<transaction_graph>(); 99 auto sgi = internal_graph; 100 101 transaction_graph::viterator_t vi, vi_end; 102 for (boost::tie(vi, vi_end) = boost::vertices(sgi); vi != vi_end; vi++) { 103 transaction_graph::oeiterator_t oei, oei_end; 104 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, sgi); oei != oei_end; 105 oei++) { 106 auto source = boost::source(*oei, sgi); 107 auto target = boost::target(*oei, sgi); 108 auto from = to_address(boost::get(boost::vertex_name_t(), sgi, source)); 109 auto to = to_address(boost::get(boost::vertex_name_t(), sgi, target)); 110 wei_t w = boost::get(boost::edge_weight_t(), sgi, *oei); 111 int64_t t = boost::get(boost::edge_timestamp_t(), sgi, *oei); 112 113 tg_ptr->add_edge(from, to, w, t); 114 } 115 } 116 return tg_ptr; 117 } 118 } // namespace rt 119 120 } // namespace neb