github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/test/runtime/nr/gtest_algo.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_algo, get_in_out_vals) { 26 neb::rt::transaction_graph tg; 27 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 28 tg.add_edge(neb::to_address("b"), neb::to_address("c"), 2, 2); 29 tg.add_edge(neb::to_address("b"), neb::to_address("d"), 3, 3); 30 tg.add_edge(neb::to_address("c"), neb::to_address("d"), 4, 4); 31 32 auto graph = tg.internal_graph(); 33 34 auto addr_and_in_out_vals_ptr = neb::rt::graph_algo::get_in_out_vals(graph); 35 auto addr_and_in_out_vals = *addr_and_in_out_vals_ptr; 36 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("a")].m_in_val == 0); 37 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("a")].m_out_val == 1); 38 39 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("b")].m_in_val == 1); 40 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("b")].m_out_val == 5); 41 42 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("c")].m_in_val == 2); 43 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("c")].m_out_val == 4); 44 45 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("d")].m_in_val == 7); 46 EXPECT_TRUE(addr_and_in_out_vals[neb::to_address("d")].m_out_val == 0); 47 } 48 49 TEST(test_algo, get_stakes) { 50 neb::rt::transaction_graph tg; 51 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 4, 4); 52 tg.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 3); 53 tg.add_edge(neb::to_address("b"), neb::to_address("d"), 2, 2); 54 tg.add_edge(neb::to_address("c"), neb::to_address("d"), 1, 1); 55 56 auto graph = tg.internal_graph(); 57 auto addr_and_stakes_ptr = neb::rt::graph_algo::get_stakes(graph); 58 auto addr_and_stakes = *addr_and_stakes_ptr; 59 60 EXPECT_TRUE(addr_and_stakes[neb::to_address("a")] == -4); 61 EXPECT_TRUE(addr_and_stakes[neb::to_address("b")] == -1); 62 EXPECT_TRUE(addr_and_stakes[neb::to_address("c")] == 2); 63 EXPECT_TRUE(addr_and_stakes[neb::to_address("d")] == 3); 64 } 65 66 TEST(test_algo, get_in_out_degree) { 67 neb::rt::transaction_graph tg; 68 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 69 tg.add_edge(neb::to_address("a"), neb::to_address("c"), 2, 2); 70 tg.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 3); 71 tg.add_edge(neb::to_address("b"), neb::to_address("d"), 4, 4); 72 tg.add_edge(neb::to_address("c"), neb::to_address("d"), 5, 5); 73 74 auto graph = tg.internal_graph(); 75 76 auto addr_and_in_out_degree_ptr = 77 neb::rt::graph_algo::get_in_out_degrees(graph); 78 auto addr_and_in_out_degree = *addr_and_in_out_degree_ptr; 79 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("a")].m_in_degree == 0); 80 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("a")].m_out_degree == 2); 81 82 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("b")].m_in_degree == 1); 83 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("b")].m_out_degree == 2); 84 85 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("c")].m_in_degree == 2); 86 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("c")].m_out_degree == 1); 87 88 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("d")].m_in_degree == 2); 89 EXPECT_TRUE(addr_and_in_out_degree[neb::to_address("d")].m_out_degree == 0); 90 } 91 92 TEST(test_algo, get_degree_sum) { 93 neb::rt::transaction_graph tg; 94 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 95 tg.add_edge(neb::to_address("a"), neb::to_address("c"), 2, 2); 96 tg.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 3); 97 tg.add_edge(neb::to_address("b"), neb::to_address("d"), 4, 4); 98 tg.add_edge(neb::to_address("c"), neb::to_address("d"), 5, 5); 99 100 auto graph = tg.internal_graph(); 101 auto addr_and_degrees_ptr = neb::rt::graph_algo::get_degree_sum(graph); 102 auto addr_and_degrees = *addr_and_degrees_ptr; 103 104 EXPECT_TRUE(addr_and_degrees[neb::to_address("a")] == 2); 105 EXPECT_TRUE(addr_and_degrees[neb::to_address("b")] == 3); 106 EXPECT_TRUE(addr_and_degrees[neb::to_address("c")] == 3); 107 EXPECT_TRUE(addr_and_degrees[neb::to_address("d")] == 2); 108 } 109 110 TEST(test_algo, merge_edges_with_same_from_and_same_to) { 111 neb::rt::transaction_graph tg; 112 tg.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1); 113 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 114 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 3, 3); 115 tg.add_edge(neb::to_address("b"), neb::to_address("a"), 4, 4); 116 117 auto graph = tg.internal_graph(); 118 neb::rt::graph_algo::merge_edges_with_same_from_and_same_to(graph); 119 120 neb::rt::transaction_graph::viterator_t vi, vi_end; 121 122 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 123 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 124 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 125 oei != oei_end; oei++) { 126 auto source = boost::source(*oei, graph); 127 auto target = boost::target(*oei, graph); 128 std::string source_name = 129 boost::get(boost::vertex_name_t(), graph, source); 130 std::string target_name = 131 boost::get(boost::vertex_name_t(), graph, target); 132 133 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 134 if (source_name.compare("a") == 0 && target_name.compare("a") == 0) { 135 EXPECT_TRUE(val == 1); 136 } else if (source_name.compare("a") == 0 && 137 target_name.compare("b") == 0) { 138 EXPECT_TRUE(val == 5); 139 } else if (source_name.compare("b") == 0 && 140 target_name.compare("a") == 0) { 141 EXPECT_TRUE(val == 4); 142 } 143 } 144 } 145 } 146 147 TEST(test_algo, merge_topk_edges_with_same_from_and_same_to_less_than_k) { 148 neb::rt::transaction_graph tg; 149 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 150 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 151 152 auto graph = tg.internal_graph(); 153 neb::rt::graph_algo::merge_topk_edges_with_same_from_and_same_to(graph); 154 155 neb::rt::transaction_graph::viterator_t vi, vi_end; 156 157 boost::tie(vi, vi_end) = boost::vertices(graph); 158 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 159 boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 160 auto source = boost::source(*oei, graph); 161 auto target = boost::target(*oei, graph); 162 std::string source_name = boost::get(boost::vertex_name_t(), graph, source); 163 std::string target_name = boost::get(boost::vertex_name_t(), graph, target); 164 EXPECT_EQ(source_name, "a"); 165 EXPECT_EQ(target_name, "b"); 166 167 int64_t timestamp = boost::get(boost::edge_timestamp_t(), graph, *oei); 168 EXPECT_EQ(timestamp, 0); 169 170 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 171 EXPECT_TRUE(val == 3); 172 } 173 174 TEST(test_algo, merge_topk_edges_with_same_from_and_same_to_equal_to_k) { 175 neb::rt::transaction_graph tg1; 176 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 177 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 178 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 3, 3); 179 180 auto graph = tg1.internal_graph(); 181 neb::rt::graph_algo::merge_topk_edges_with_same_from_and_same_to(graph); 182 183 neb::rt::transaction_graph::viterator_t vi, vi_end; 184 boost::tie(vi, vi_end) = boost::vertices(graph); 185 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 186 boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 187 auto source = boost::source(*oei, graph); 188 auto target = boost::target(*oei, graph); 189 std::string source_name = boost::get(boost::vertex_name_t(), graph, source); 190 std::string target_name = boost::get(boost::vertex_name_t(), graph, target); 191 EXPECT_EQ(source_name, "a"); 192 EXPECT_EQ(target_name, "b"); 193 194 int64_t timestamp = boost::get(boost::edge_timestamp_t(), graph, *oei); 195 EXPECT_EQ(timestamp, 0); 196 197 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 198 EXPECT_TRUE(val == 6); 199 } 200 201 TEST(test_algo, merge_topk_edges_with_same_from_and_same_to_larger_than_k) { 202 neb::rt::transaction_graph tg2; 203 tg2.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 204 tg2.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 205 tg2.add_edge(neb::to_address("a"), neb::to_address("b"), 3, 3); 206 tg2.add_edge(neb::to_address("a"), neb::to_address("b"), 4, 4); 207 208 auto graph = tg2.internal_graph(); 209 neb::rt::graph_algo::merge_topk_edges_with_same_from_and_same_to(graph); 210 211 neb::rt::transaction_graph::viterator_t vi, vi_end; 212 boost::tie(vi, vi_end) = boost::vertices(graph); 213 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 214 boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 215 216 auto source = boost::source(*oei, graph); 217 auto target = boost::target(*oei, graph); 218 std::string source_name = boost::get(boost::vertex_name_t(), graph, source); 219 std::string target_name = boost::get(boost::vertex_name_t(), graph, target); 220 EXPECT_EQ(source_name, "a"); 221 EXPECT_EQ(target_name, "b"); 222 223 int64_t timestamp = boost::get(boost::edge_timestamp_t(), graph, *oei); 224 EXPECT_EQ(timestamp, 0); 225 226 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 227 EXPECT_TRUE(val != 6); 228 EXPECT_TRUE(val == 9); 229 } 230 231 // class private func 232 TEST(test_algo, merge_two_graphs) { 233 neb::rt::transaction_graph tg1; 234 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 235 tg1.add_edge(neb::to_address("a"), neb::to_address("c"), 2, 2); 236 237 neb::rt::transaction_graph tg2; 238 tg2.add_edge(neb::to_address("a"), neb::to_address("c"), 3, 3); 239 tg2.add_edge(neb::to_address("a"), neb::to_address("d"), 4, 4); 240 tg2.add_edge(neb::to_address("c"), neb::to_address("d"), 5, 5); 241 242 neb::rt::transaction_graph_ptr_t ptr1 = 243 std::make_unique<neb::rt::transaction_graph>(tg1); 244 neb::rt::transaction_graph_ptr_t ptr2 = 245 std::make_unique<neb::rt::transaction_graph>(tg2); 246 neb::rt::graph_algo::merge_two_graphs(ptr1.get(), ptr2.get()); 247 248 neb::rt::transaction_graph::viterator_t vi, vi_end; 249 250 auto graph = ptr1->internal_graph(); 251 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 252 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 253 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 254 oei != oei_end; oei++) { 255 auto source = boost::source(*oei, graph); 256 auto target = boost::target(*oei, graph); 257 std::string source_name = 258 boost::get(boost::vertex_name_t(), graph, source); 259 std::string target_name = 260 boost::get(boost::vertex_name_t(), graph, target); 261 262 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 263 if (source_name.compare("a") == 0 && target_name.compare("b") == 0) { 264 EXPECT_TRUE(val == 1); 265 } else if (source_name.compare("a") == 0 && 266 target_name.compare("c") == 0) { 267 EXPECT_TRUE(val == 2 || val == 3); 268 } else if (source_name.compare("a") == 0 && 269 target_name.compare("d") == 0) { 270 EXPECT_TRUE(val == 4); 271 } else if (source_name.compare("c") == 0 && 272 target_name.compare("d") == 0) { 273 EXPECT_TRUE(val == 5); 274 } 275 } 276 } 277 } 278 279 TEST(test_algo, merge_graphs) { 280 neb::rt::transaction_graph tg1; 281 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 1); 282 tg1.add_edge(neb::to_address("a"), neb::to_address("c"), 2, 2); 283 284 neb::rt::transaction_graph tg2; 285 tg2.add_edge(neb::to_address("a"), neb::to_address("c"), 3, 3); 286 tg2.add_edge(neb::to_address("a"), neb::to_address("d"), 4, 4); 287 tg2.add_edge(neb::to_address("c"), neb::to_address("d"), 5, 5); 288 289 neb::rt::transaction_graph tg3; 290 tg3.add_edge(neb::to_address("e"), neb::to_address("f"), 6, 6); 291 tg3.add_edge(neb::to_address("f"), neb::to_address("b"), 7, 7); 292 tg3.add_edge(neb::to_address("c"), neb::to_address("f"), 8, 8); 293 294 neb::rt::transaction_graph_ptr_t ptr1 = 295 std::make_unique<neb::rt::transaction_graph>(tg1); 296 neb::rt::transaction_graph_ptr_t ptr2 = 297 std::make_unique<neb::rt::transaction_graph>(tg2); 298 neb::rt::transaction_graph_ptr_t ptr3 = 299 std::make_unique<neb::rt::transaction_graph>(tg3); 300 std::vector<neb::rt::transaction_graph_ptr_t> v; 301 v.push_back(std::move(ptr1)); 302 v.push_back(std::move(ptr2)); 303 v.push_back(std::move(ptr3)); 304 auto ptr = neb::rt::graph_algo::merge_graphs(v); 305 306 neb::rt::transaction_graph::viterator_t vi, vi_end; 307 308 auto graph = ptr->internal_graph(); 309 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 310 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 311 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 312 oei != oei_end; oei++) { 313 auto source = boost::source(*oei, graph); 314 auto target = boost::target(*oei, graph); 315 std::string source_name = 316 boost::get(boost::vertex_name_t(), graph, source); 317 std::string target_name = 318 boost::get(boost::vertex_name_t(), graph, target); 319 320 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 321 if (source_name.compare("a") == 0 && target_name.compare("b") == 0) { 322 EXPECT_TRUE(val == 1); 323 } else if (source_name.compare("a") == 0 && 324 target_name.compare("c") == 0) { 325 EXPECT_TRUE(val == 2 || val == 3); 326 } else if (source_name.compare("a") == 0 && 327 target_name.compare("d") == 0) { 328 EXPECT_TRUE(val == 4); 329 } else if (source_name.compare("c") == 0 && 330 target_name.compare("d") == 0) { 331 EXPECT_TRUE(val == 5); 332 } else if (source_name.compare("e") == 0 && 333 target_name.compare("f") == 0) { 334 EXPECT_TRUE(val == 6); 335 } else if (source_name.compare("f") == 0 && 336 target_name.compare("b") == 0) { 337 EXPECT_TRUE(val == 7); 338 } else if (source_name.compare("c") == 0 && 339 target_name.compare("f") == 0) { 340 EXPECT_TRUE(val == 8); 341 } 342 } 343 } 344 } 345 346 TEST(test_algo, find_a_cycle_based_on_time_sequence) { 347 neb::rt::transaction_graph tg; 348 tg.add_edge(neb::to_address("a"), neb::to_address("b"), 1, 5); 349 tg.add_edge(neb::to_address("d"), neb::to_address("a"), 2, 1); 350 tg.add_edge(neb::to_address("b"), neb::to_address("d"), 3, 2); 351 tg.add_edge(neb::to_address("c"), neb::to_address("b"), 4, 4); 352 tg.add_edge(neb::to_address("d"), neb::to_address("c"), 5, 3); 353 354 auto graph = tg.internal_graph(); 355 auto cycle = 356 neb::rt::graph_algo::find_a_cycle_based_on_time_sequence(graph, {}); 357 358 auto it = cycle.begin(); 359 auto source = boost::source(*it, graph); 360 auto target = boost::target(*it, graph); 361 std::string source_name = boost::get(boost::vertex_name_t(), graph, source); 362 std::string target_name = boost::get(boost::vertex_name_t(), graph, target); 363 auto ts = boost::get(boost::edge_timestamp_t(), graph, *it); 364 EXPECT_TRUE(source_name.compare("b") == 0 && target_name.compare("d") == 0 && 365 ts == 2); 366 it++; 367 368 source = boost::source(*it, graph); 369 target = boost::target(*it, graph); 370 source_name = boost::get(boost::vertex_name_t(), graph, source); 371 target_name = boost::get(boost::vertex_name_t(), graph, target); 372 ts = boost::get(boost::edge_timestamp_t(), graph, *it); 373 EXPECT_TRUE(source_name.compare("d") == 0 && target_name.compare("c") == 0 && 374 ts == 3); 375 it++; 376 377 source = boost::source(*it, graph); 378 target = boost::target(*it, graph); 379 source_name = boost::get(boost::vertex_name_t(), graph, source); 380 target_name = boost::get(boost::vertex_name_t(), graph, target); 381 ts = boost::get(boost::edge_timestamp_t(), graph, *it); 382 EXPECT_TRUE(source_name.compare("c") == 0 && target_name.compare("b") == 0 && 383 ts == 4); 384 it++; 385 } 386 387 TEST(test_algo, remove_cycles_based_on_time_sequence_case1) { 388 neb::rt::transaction_graph tg1; 389 tg1.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1); 390 tg1.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 391 tg1.add_edge(neb::to_address("b"), neb::to_address("a"), 3, 3); 392 tg1.add_edge(neb::to_address("b"), neb::to_address("c"), 4, 4); 393 tg1.add_edge(neb::to_address("c"), neb::to_address("a"), 5, 5); 394 395 auto graph = tg1.internal_graph(); 396 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 397 398 neb::rt::transaction_graph::viterator_t vi, vi_end; 399 400 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 401 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 402 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 403 oei != oei_end; oei++) { 404 auto source = boost::source(*oei, graph); 405 auto target = boost::target(*oei, graph); 406 std::string source_name = 407 boost::get(boost::vertex_name_t(), graph, source); 408 std::string target_name = 409 boost::get(boost::vertex_name_t(), graph, target); 410 411 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 412 int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei); 413 if (source_name.compare("b") == 0 && target_name.compare("a") == 0) { 414 EXPECT_TRUE(val == 1 && ts == 3); 415 } else if (source_name.compare("b") == 0 && 416 target_name.compare("c") == 0) { 417 EXPECT_TRUE(val == 4 && ts == 4); 418 } else if (source_name.compare("c") == 0 && 419 target_name.compare("a") == 0) { 420 EXPECT_TRUE(val == 5 && ts == 5); 421 } 422 } 423 } 424 } 425 426 TEST(test_algo, remove_cycles_based_on_time_sequence_case2) { 427 neb::rt::transaction_graph tg2; 428 tg2.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1); 429 tg2.add_edge(neb::to_address("a"), neb::to_address("c"), 2, 3); 430 tg2.add_edge(neb::to_address("c"), neb::to_address("a"), 3, 2); 431 tg2.add_edge(neb::to_address("c"), neb::to_address("b"), 4, 4); 432 tg2.add_edge(neb::to_address("b"), neb::to_address("a"), 5, 5); 433 434 auto graph = tg2.internal_graph(); 435 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 436 437 neb::rt::transaction_graph::viterator_t vi, vi_end; 438 439 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 440 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 441 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 442 oei != oei_end; oei++) { 443 auto source = boost::source(*oei, graph); 444 auto target = boost::target(*oei, graph); 445 std::string source_name = 446 boost::get(boost::vertex_name_t(), graph, source); 447 std::string target_name = 448 boost::get(boost::vertex_name_t(), graph, target); 449 450 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 451 int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei); 452 if (source_name.compare("c") == 0 && target_name.compare("a") == 0) { 453 EXPECT_TRUE(val == 3 && ts == 2); 454 } else if (source_name.compare("c") == 0 && 455 target_name.compare("b") == 0) { 456 EXPECT_TRUE(val == 2 && ts == 4); 457 } else if (source_name.compare("b") == 0 && 458 target_name.compare("a") == 0) { 459 EXPECT_TRUE(val == 3 && ts == 5); 460 } 461 } 462 } 463 } 464 465 TEST(test_algo, remove_cycles_based_on_time_sequence_case3) { 466 neb::rt::transaction_graph tg3; 467 tg3.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1); 468 tg3.add_edge(neb::to_address("a"), neb::to_address("b"), 3, 2); 469 tg3.add_edge(neb::to_address("b"), neb::to_address("a"), 1, 3); 470 tg3.add_edge(neb::to_address("b"), neb::to_address("c"), 2, 4); 471 tg3.add_edge(neb::to_address("c"), neb::to_address("a"), 2, 5); 472 473 auto graph = tg3.internal_graph(); 474 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 475 476 neb::rt::transaction_graph::viterator_t vi, vi_end; 477 478 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 479 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 480 boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 481 EXPECT_TRUE(oei == oei_end); 482 } 483 } 484 485 TEST(test_algo, remove_cycles_based_on_time_sequence_case4) { 486 neb::rt::transaction_graph tg4; 487 tg4.add_edge(neb::to_address("a"), neb::to_address("a"), 1, 1); 488 tg4.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 489 tg4.add_edge(neb::to_address("b"), neb::to_address("a"), 3, 1); 490 tg4.add_edge(neb::to_address("b"), neb::to_address("c"), 2, 3); 491 tg4.add_edge(neb::to_address("c"), neb::to_address("a"), 1, 4); 492 tg4.add_edge(neb::to_address("c"), neb::to_address("a"), 2, 4); 493 494 auto graph = tg4.internal_graph(); 495 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 496 497 neb::rt::transaction_graph::viterator_t vi, vi_end; 498 499 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 500 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 501 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 502 oei != oei_end; oei++) { 503 auto source = boost::source(*oei, graph); 504 auto target = boost::target(*oei, graph); 505 std::string source_name = 506 boost::get(boost::vertex_name_t(), graph, source); 507 std::string target_name = 508 boost::get(boost::vertex_name_t(), graph, target); 509 510 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 511 int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei); 512 if (source_name.compare("b") == 0 && target_name.compare("a") == 0) { 513 EXPECT_TRUE(val == 3 && ts == 1); 514 } else if (source_name.compare("c") == 0 && 515 target_name.compare("a") == 0) { 516 EXPECT_TRUE(val == 1 && ts == 4); 517 } 518 } 519 } 520 } 521 522 TEST(test_algo, remove_cycles_based_on_time_sequence_case5) { 523 neb::rt::transaction_graph tg5; 524 tg5.add_edge(neb::to_address("a"), neb::to_address("b"), 2, 2); 525 tg5.add_edge(neb::to_address("b"), neb::to_address("c"), 3, 1); 526 tg5.add_edge(neb::to_address("c"), neb::to_address("d"), 1, 4); 527 tg5.add_edge(neb::to_address("d"), neb::to_address("b"), 2, 4); 528 529 auto graph = tg5.internal_graph(); 530 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 531 532 neb::rt::transaction_graph::viterator_t vi, vi_end; 533 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 534 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 535 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 536 oei != oei_end; oei++) { 537 auto source = boost::source(*oei, graph); 538 auto target = boost::target(*oei, graph); 539 std::string source_name = 540 boost::get(boost::vertex_name_t(), graph, source); 541 std::string target_name = 542 boost::get(boost::vertex_name_t(), graph, target); 543 544 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 545 int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei); 546 if (source_name.compare("a") == 0 && target_name.compare("b") == 0) { 547 EXPECT_TRUE(val == 2 && ts == 2); 548 } else if (source_name.compare("b") == 0 && 549 target_name.compare("c") == 0) { 550 EXPECT_TRUE(val == 3 && ts == 1); 551 } else if (source_name.compare("c") == 0 && 552 target_name.compare("d") == 0) { 553 EXPECT_TRUE(val == 1 && ts == 4); 554 } else if (source_name.compare("d") == 0 && 555 target_name.compare("b") == 0) { 556 EXPECT_TRUE(val == 2 && ts == 4); 557 } 558 } 559 } 560 } 561 562 TEST(test_algo, remove_cycles_based_on_time_sequence_case6) { 563 neb::rt::transaction_graph tg6; 564 char cc = 'b'; 565 int32_t n = 3; 566 for (char ch = 'a'; ch < cc; ch++) { 567 for (int32_t i = 0; i < n; i++) { 568 tg6.add_edge(neb::to_address(std::string(1, ch)), 569 neb::to_address(std::string(1, ch + 1)), ch - 'a' + 1, 570 ch - 'a' + 1); 571 } 572 } 573 for (int32_t i = 0; i < n; i++) { 574 tg6.add_edge(neb::to_address(std::string(1, cc)), 575 neb::to_address(std::string(1, 'a')), cc - 'a' + 1, 576 cc - 'a' + 1); 577 } 578 579 auto graph = tg6.internal_graph(); 580 neb::rt::graph_algo::remove_cycles_based_on_time_sequence(graph); 581 582 neb::rt::transaction_graph::viterator_t vi, vi_end; 583 for (boost::tie(vi, vi_end) = boost::vertices(graph); vi != vi_end; vi++) { 584 neb::rt::transaction_graph::oeiterator_t oei, oei_end; 585 for (boost::tie(oei, oei_end) = boost::out_edges(*vi, graph); 586 oei != oei_end; oei++) { 587 auto source = boost::source(*oei, graph); 588 auto target = boost::target(*oei, graph); 589 std::string source_name = 590 boost::get(boost::vertex_name_t(), graph, source); 591 std::string target_name = 592 boost::get(boost::vertex_name_t(), graph, target); 593 EXPECT_EQ(source_name, "b"); 594 EXPECT_EQ(target_name, "a"); 595 596 neb::wei_t val = boost::get(boost::edge_weight_t(), graph, *oei); 597 LOG(INFO) << val; 598 int64_t ts = boost::get(boost::edge_timestamp_t(), graph, *oei); 599 EXPECT_EQ(ts, 2); 600 } 601 } 602 } 603