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