github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/test/runtime/nr/gtest_decycle.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  
    21  #include "common/common.h"
    22  #include "runtime/nr/graph/algo.h"
    23  #include <gtest/gtest.h>
    24  
    25  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case1) {
    26    neb::rt::transaction_graph tg;
    27    tg.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1);
    28    tg.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2);
    29    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 3);
    30    tg.add_edge(neb::to_address("c"), neb::to_address("a"), 4, 4);
    31  
    32    auto graph = tg.internal_graph();
    33    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
    34        graph);
    35  
    36    neb::rt::transaction_graph::viterator_t vi, vi_end;
    37  
    38    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
    39      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
    40      for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
    41           oei != oei_end; oei++) {
    42        auto source = boost::source(*oei, graph);
    43        auto target = boost::target(*oei, graph);
    44        std::string source_name =
    45            boost::get(boost::vertex_name_t(), graph, source);
    46        std::string target_name =
    47            boost::get(boost::vertex_name_t(), graph, target);
    48  
    49        neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei);
    50        int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei);
    51        if (source_name.compare("b") == 0 && target_name.compare("c") == 0) {
    52          EXPECT_TRUE(val == 1 && ts == 3);
    53        } else if (source_name.compare("c") == 0 &&
    54                   target_name.compare("a") == 0) {
    55          EXPECT_TRUE(val == 2 && ts == 4);
    56        }
    57      }
    58    }
    59  }
    60  
    61  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case2) {
    62    neb::rt::transaction_graph tg;
    63    tg.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1);
    64    tg.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 3);
    65    tg.add_edge(neb::to_address("b"), neb::to_address("a"), 3, 2);
    66    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 4, 1);
    67    tg.add_edge(neb::to_address("c"), neb::to_address("a"), 5, 5);
    68  
    69    auto graph = tg.internal_graph();
    70    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
    71        graph);
    72    tg.write_to_graphviz("case2.txt");
    73  
    74    neb::rt::transaction_graph::viterator_t vi, vi_end;
    75  
    76    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
    77      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
    78      for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
    79           oei != oei_end; oei++) {
    80        auto source = boost::source(*oei, graph);
    81        auto target = boost::target(*oei, graph);
    82        std::string source_name =
    83            boost::get(boost::vertex_name_t(), graph, source);
    84        std::string target_name =
    85            boost::get(boost::vertex_name_t(), graph, target);
    86  
    87        neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei);
    88        int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei);
    89        if (source_name.compare("b") == 0 && target_name.compare("a") == 0) {
    90          EXPECT_TRUE(val == 1 && ts == 2) << "val: " << val;
    91        } else if (source_name.compare("c") == 0 &&
    92                   target_name.compare("b") == 0) {
    93          EXPECT_TRUE(val == 4 && ts == 1);
    94        } else if (source_name.compare("b") == 0 &&
    95                   target_name.compare("a") == 0) {
    96          EXPECT_TRUE(val == 5 && ts == 5);
    97        }
    98      }
    99    }
   100  }
   101  
   102  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case3) {
   103    neb::rt::transaction_graph tg;
   104    tg.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1);
   105    tg.add_edge(neb::to_address("a"), neb::to_address("b"), 3, 2);
   106    tg.add_edge(neb::to_address("b"), neb::to_address("a"), 1, 3);
   107    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 2, 4);
   108    tg.add_edge(neb::to_address("c"), neb::to_address("a"), 2, 5);
   109  
   110    auto graph = tg.internal_graph();
   111    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   112        graph);
   113  
   114    neb::rt::transaction_graph::viterator_t vi, vi_end;
   115    tg.write_to_graphviz("case3.txt");
   116  
   117    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
   118      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
   119      boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
   120      EXPECT_TRUE(oei == oei_end);
   121    }
   122  }
   123  
   124  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case4) {
   125    neb::rt::transaction_graph tg;
   126    tg.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2);
   127    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 1);
   128    tg.add_edge(neb::to_address("c"), neb::to_address("d"), 1, 4);
   129    tg.add_edge(neb::to_address("d"), neb::to_address("b"), 2, 4);
   130  
   131    auto graph = tg.internal_graph();
   132    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   133        graph);
   134  
   135    neb::rt::transaction_graph::viterator_t vi, vi_end;
   136    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
   137      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
   138      for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
   139           oei != oei_end; oei++) {
   140        auto source = boost::source(*oei, graph);
   141        auto target = boost::target(*oei, graph);
   142        std::string source_name =
   143            boost::get(boost::vertex_name_t(), graph, source);
   144        std::string target_name =
   145            boost::get(boost::vertex_name_t(), graph, target);
   146  
   147        neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei);
   148        int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei);
   149        if (source_name.compare("a") == 0 && target_name.compare("b") == 0) {
   150          EXPECT_TRUE(val == 2 && ts == 2);
   151        } else if (source_name.compare("b") == 0 &&
   152                   target_name.compare("c") == 0) {
   153          EXPECT_TRUE(val == 2 && ts == 1);
   154        } else if (source_name.compare("d") == 0 &&
   155                   target_name.compare("b") == 0) {
   156          EXPECT_TRUE(val == 1 && ts == 4);
   157        }
   158      }
   159    }
   160  }
   161  
   162  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case5) {
   163    neb::rt::transaction_graph tg;
   164    char cc = 'z';
   165    int32_t n = 1000;
   166    for (char ch = 'a'; ch < cc; ch++) {
   167      for (int32_t i = 0; i < n; i++) {
   168        tg.add_edge(neb::to_address(std::string(1, ch)),
   169                    neb::to_address(std::string(1, ch + 1)), ch - 'a' + 1,
   170                    ch - 'a' + 1);
   171      }
   172    }
   173    for (int32_t i = 0; i < n; i++) {
   174      tg.add_edge(neb::to_address(std::string(1, cc)),
   175                  neb::to_address(std::string(1, 'a')), cc - 'a' + 1,
   176                  cc - 'a' + 1);
   177    }
   178  
   179    auto graph = tg.internal_graph();
   180    LOG(INFO) << boost::num_vertices(graph);
   181    LOG(INFO) << boost::num_edges(graph);
   182    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   183        graph);
   184  }
   185  
   186  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case6) {
   187    neb::rt::transaction_graph tg;
   188    char cc = 'z';
   189    int32_t n = 100;
   190    for (char ch = 'a'; ch <= cc; ch++) {
   191      for (int32_t i = 0; i < n; i++) {
   192        tg.add_edge(neb::to_address(std::string(1, ch)),
   193                    neb::to_address(std::string(1, ch)), ch - 'a' + 1,
   194                    ch - 'a' + 1);
   195      }
   196    }
   197  
   198    auto graph = tg.internal_graph();
   199    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   200        graph);
   201    EXPECT_EQ(boost::num_vertices(graph), cc - 'a' + 1);
   202    EXPECT_EQ(boost::num_edges(graph), 0);
   203  }
   204  
   205  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case7) {
   206    neb::rt::transaction_graph tg;
   207    tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1);
   208    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 2, 1);
   209    tg.add_edge(neb::to_address("c"), neb::to_address("d"), 3, 2);
   210    tg.add_edge(neb::to_address("d"), neb::to_address("a"), 4, 2);
   211  
   212    auto graph = tg.internal_graph();
   213    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   214        graph);
   215  
   216    neb::rt::transaction_graph::viterator_t vi, vi_end;
   217    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
   218      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
   219      for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
   220           oei != oei_end; oei++) {
   221        auto source = boost::source(*oei, graph);
   222        auto target = boost::target(*oei, graph);
   223        std::string source_name =
   224            boost::get(boost::vertex_name_t(), graph, source);
   225        std::string target_name =
   226            boost::get(boost::vertex_name_t(), graph, target);
   227  
   228        neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei);
   229        int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei);
   230        if (source_name.compare("b") == 0 && target_name.compare("c") == 0) {
   231          EXPECT_TRUE(val == 1 && ts == 1);
   232        } else if (source_name.compare("c") == 0 &&
   233                   target_name.compare("d") == 0) {
   234          EXPECT_TRUE(val == 2 && ts == 2);
   235        } else if (source_name.compare("d") == 0 &&
   236                   target_name.compare("a") == 0) {
   237          EXPECT_TRUE(val == 3 && ts == 2);
   238        }
   239      }
   240    }
   241  }
   242  
   243  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case8) {
   244    neb::rt::transaction_graph tg;
   245    tg.add_edge(neb::to_address("b"), neb::to_address("c"), 1, 1);
   246    tg.add_edge(neb::to_address("c"), neb::to_address("d"), 2, 2);
   247    tg.add_edge(neb::to_address("d"), neb::to_address("b"), 3, 3);
   248    tg.add_edge(neb::to_address("a"), neb::to_address("d"), 1, 1);
   249    tg.add_edge(neb::to_address("b"), neb::to_address("a"), 2, 2);
   250  
   251    auto graph = tg.internal_graph();
   252    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   253        graph);
   254  
   255    neb::rt::transaction_graph::viterator_t vi, vi_end;
   256    for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) {
   257      neb::rt::transaction_graph::oeiterator_t oei, oei_end;
   258      for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph);
   259           oei != oei_end; oei++) {
   260        auto source = boost::source(*oei, graph);
   261        auto target = boost::target(*oei, graph);
   262        std::string source_name =
   263            boost::get(boost::vertex_name_t(), graph, source);
   264        std::string target_name =
   265            boost::get(boost::vertex_name_t(), graph, target);
   266  
   267        neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei);
   268        int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei);
   269        if (source_name.compare("c") == 0 && target_name.compare("d") == 0) {
   270          EXPECT_TRUE(val == 1 && ts == 2);
   271        } else if (source_name.compare("d") == 0 &&
   272                   target_name.compare("b") == 0) {
   273          EXPECT_TRUE(val == 2 && ts == 3);
   274        } else if (source_name.compare("a") == 0 &&
   275                   target_name.compare("d") == 0) {
   276          EXPECT_TRUE(val == 1 && ts == 1);
   277        } else if (source_name.compare("b") == 0 &&
   278                   target_name.compare("a") == 0) {
   279          EXPECT_TRUE(val == 2 && ts == 2);
   280        }
   281      }
   282    }
   283  }
   284  
   285  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case9) {
   286    neb::rt::transaction_graph tg;
   287    char cc = 'z';
   288    int32_t n = 100;
   289    for (char ch = 'a'; ch < cc; ch++) {
   290      for (int32_t i = 0; i < n; i++) {
   291        tg.add_edge(neb::to_address(std::string(1, ch)),
   292                    neb::to_address(std::string(1, ch + 1)), ch - 'a' + 1,
   293                    ch - 'a' + 1);
   294      }
   295    }
   296  
   297    auto &graph = tg.internal_graph();
   298    auto before_v_nums = boost::num_vertices(graph);
   299    auto before_e_nums = boost::num_edges(graph);
   300    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   301        graph);
   302    auto after_v_nums = boost::num_vertices(graph);
   303    auto after_e_nums = boost::num_edges(graph);
   304    EXPECT_EQ(before_v_nums, after_v_nums);
   305    EXPECT_EQ(before_e_nums, after_e_nums);
   306  }
   307  
   308  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case10) {
   309    neb::rt::transaction_graph tg;
   310    std::queue<char> q;
   311    char cc = 'z';
   312    int32_t n = 2;
   313    q.push('a');
   314    char tail = 'a';
   315    while (!q.empty()) {
   316      auto &ele = q.front();
   317      q.pop();
   318      char tmp_tail = tail;
   319      if (tail + n < cc) {
   320        for (auto i = 1; i <= n; i++) {
   321          tg.add_edge(neb::to_address(std::string(1, ele)),
   322                      neb::to_address(std::string(1, tmp_tail + i)),
   323                      ele - 'a' + 1, ele - 'a' + 1);
   324          q.push(tmp_tail + i);
   325          tail++;
   326        }
   327        tmp_tail = tail;
   328      }
   329    }
   330  
   331    auto graph = tg.internal_graph();
   332    auto before_v_nums = boost::num_vertices(graph);
   333    auto before_e_nums = boost::num_edges(graph);
   334    LOG(INFO) << before_v_nums << ',' << before_e_nums;
   335    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   336        graph);
   337    auto after_v_nums = boost::num_vertices(graph);
   338    auto after_e_nums = boost::num_edges(graph);
   339    EXPECT_EQ(before_v_nums, after_v_nums);
   340    EXPECT_EQ(before_e_nums, after_e_nums);
   341  }
   342  
   343  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case11) {
   344    neb::rt::transaction_graph tg;
   345    char cc = 'z';
   346    int32_t n = 5;
   347    int32_t tmp = cc - 'a' + 1;
   348  
   349    for (char s = 'a'; s <= cc; s++) {
   350      for (char t = 'a'; t <= cc; t++) {
   351        int32_t s_ch = s - 'a' + 1;
   352        int32_t t_ch = t - 'a' + 1;
   353        for (int32_t i = 0; i < n; i++) {
   354          tg.add_edge(neb::to_address(std::string(1, s)),
   355                      neb::to_address(std::string(1, t)), s_ch + tmp * t_ch + 1,
   356                      s_ch + tmp * t_ch + 1);
   357        }
   358      }
   359    }
   360  
   361    auto graph = tg.internal_graph();
   362    LOG(INFO) << "edge num: " << tg.edge_num();
   363    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   364        graph);
   365  }
   366  
   367  TEST(test_decycle, non_recursive_remove_cycles_based_on_time_sequence_case12) {
   368    neb::rt::transaction_graph tg;
   369    char cc = 'z';
   370    char ch_half = cc / 2;
   371    int32_t n = 10;
   372    int32_t tmp = cc - 'a' + 1;
   373  
   374    for (char s = 'a'; s < ch_half; s++) {
   375      for (char t = ch_half; t <= cc; t++) {
   376        int32_t s_ch = s - 'a' + 1;
   377        int32_t t_ch = t - 'a' + 1;
   378        for (int32_t i = 0; i < n; i++) {
   379          tg.add_edge(neb::to_address(std::string(1, s)),
   380                      neb::to_address(std::string(1, t)), s_ch + tmp * t_ch + 1,
   381                      s_ch + tmp * t_ch + 1);
   382        }
   383      }
   384    }
   385  
   386    auto graph = tg.internal_graph();
   387    neb::rt::graph_algo::non_recursive_remove_cycles_based_on_time_sequence(
   388        graph);
   389  }
   390