// File: /workspace/github_cpp_makefile_star2_O2/kulpreet[P]lightning-network-graph-analysis/src/include/algos.hpp
// Function: lncentrality::find_non_singleton_components(std::vector<unsigned long, std::allocator<unsigned long>>&, boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, lncentrality::LitVertex, lncentrality::LitEdge, boost::no_property, boost::listS>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&)
void find_non_singleton_components(std::vector<Vertex> &art_points, LitGraph &g,
                                   string &stem, string &outdir) {

  // make a map component id to component size
  std::map<int, int> component_sizes;
  std::vector<Vertex>::iterator i;
  std::ofstream out;

  graph_traits<LitGraph>::edge_iterator ei, ei_end;
  graph_traits<LitGraph>::out_edge_iterator out_i, out_end;

  typedef graph_traits<LitGraph>::edge_descriptor Edge;
  std::vector<Edge> bridges;
  std::set<int> component_ids;
  std::map<int, set<int>> interesting_art_points;
  int num_interesting;

  // find the size of components by iterating over all edges.
  for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    component_sizes[g[*ei].component]++;
  }

  // iterate over all edges again and select those edges where
  // component size on both vertices are greater than 1. This and the
  // previous loop can probably be optimised.
  for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
    if (component_sizes[g[*ei].component] == 1) {
      bridges.push_back(*ei);
    }
  }

  // iterate over all art points
  for (i = art_points.begin(); i != art_points.end(); i++) {
    // get all the components for all the edges of the art points
    component_ids.clear();
    for (boost::tie(out_i, out_end) = out_edges(*i, g); out_i != out_end;
         ++out_i) {
      component_ids.insert(g[*out_i].component);
    }
    // find the number of components the art point is connecting
    num_interesting =
        std::accumulate(component_ids.begin(), component_ids.end(), 0,
                        [&component_sizes](int a, int cid) {
                          if (component_sizes[cid] > 5) {
                            a = a + 1;
                          }
                          return a;
                        });
    // change the min size of components to consider "interesting"
    if (num_interesting > 1) {
      interesting_art_points[*i] = component_ids;
    }
  }

  // date, #components, #interesting art points. No header output as
  // this is appended to file.
  out.open(outdir + "/key_ap_stats.csv", std::fstream::out | std::fstream::app);
  out << stem << "," << component_sizes.size() << ","
      << interesting_art_points.size() << std::endl;
  out.close();

  out.open(outdir + "/" + stem + ".key_ap.csv",
           std::fstream::out | std::fstream::trunc);

  // Key Articulation Points. Header included.
  out << "alias,num components,degree,pub_key" << std::endl;
  for (std::map<int, set<int>>::iterator x = interesting_art_points.begin();
       x != interesting_art_points.end(); x++) {
    out << "\"" << g[x->first].name << "\""
        << "," << (x->second).size() << "," << degree(x->first, g) << ","
        << g[x->first].pub_key << endl;
  }
  out.close();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x338, %rsp            # imm = 0x338
movq %rcx, %r12
movq %rdx, %r15
movq %rsi, %rbp
movq %rdi, 0x28(%rsp)
leaq 0xa0(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x138(%rsp), %rdi
callq 0x7500
andq $0x0, 0x60(%rsp)
leaq 0x110(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x70(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
xorps %xmm0, %xmm0
movaps %xmm0, 0x50(%rsp)
leaq 0x98(%rsp), %r14
movq %rbp, %rbx
movq (%rbx), %rbx
cmpq %rbp, %rbx
je 0x7ed0
leaq 0xf8(%rbx), %rsi
movq %r14, %rdi
callq 0x9136
incl (%rax)
jmp 0x7eb5
movq %r12, 0x38(%rsp)
movq %r15, 0x30(%rsp)
leaq 0x98(%rsp), %r14
leaq 0x50(%rsp), %r15
movq %rsp, %r13
movq %rbp, %rbx
movq (%rbx), %rbx
cmpq %rbp, %rbx
je 0x7f27
leaq 0xf8(%rbx), %rsi
movq %r14, %rdi
callq 0x9136
cmpl $0x1, (%rax)
jne 0x7eed
leaq 0x20(%rbx), %rax
movups 0x10(%rbx), %xmm0
movaps %xmm0, (%rsp)
movq %rax, 0x10(%rsp)
movq %r15, %rdi
movq %r13, %rsi
callq 0xc4fc
jmp 0x7eed
movq 0x28(%rsp), %rax
movq (%rax), %r12
leaq 0x108(%rsp), %r13
movq %rsp, %r14
leaq 0x98(%rsp), %r15
movl $0xf8, %ebx
movq %rbp, 0x40(%rsp)
movq 0x28(%rsp), %rax
cmpq 0x8(%rax), %r12
je 0x8011
movq %r13, %rdi
callq 0xc616
movq 0x18(%rbp), %rax
movq %r12, 0x48(%rsp)
imulq $0xb8, (%r12), %rcx
movq (%rax,%rcx), %r12
movq 0x8(%rax,%rcx), %rbp
cmpq %rbp, %r12
je 0x7f98
movq 0x8(%r12), %rsi
addq %rbx, %rsi
movq %r13, %rdi
callq 0xc644
addq $0x10, %r12
jmp 0x7f7d
xorl %r12d, %r12d
movq 0x120(%rsp), %rbp
leaq 0x110(%rsp), %rax
cmpq %rax, %rbp
je 0x7fd9
movl 0x20(%rbp), %eax
movl %eax, (%rsp)
movq %r15, %rdi
movq %r14, %rsi
callq 0x9136
xorl %ecx, %ecx
cmpl $0x6, (%rax)
setge %cl
addl %ecx, %r12d
movq %rbp, %rdi
callq 0x7340
movq %rax, %rbp
jmp 0x7fa3
cmpl $0x2, %r12d
movq 0x40(%rsp), %rbp
movq 0x48(%rsp), %r12
jb 0x8008
movl (%r12), %eax
movl %eax, (%rsp)
leaq 0x68(%rsp), %rdi
movq %r14, %rsi
callq 0x9184
movq %rax, %rdi
movq %r13, %rsi
callq 0x9432
addq $0x8, %r12
jmp 0x7f4c
leaq 0x110da(%rip), %rdx     # 0x190f2
movq %rsp, %rdi
movq 0x38(%rsp), %r15
movq %r15, %rsi
callq 0x9066
leaq 0x138(%rsp), %rdi
movq %rsp, %rsi
pushq $0x11
popq %rdx
callq 0x7190
leaq 0x70(%rsp), %rbx
movq 0x30(%rsp), %r14
movq %rsp, %rdi
callq 0x7180
leaq 0x138(%rsp), %rdi
movq %r14, %rsi
callq 0x72c0
leaq 0x11062(%rip), %rsi     # 0x190c6
movq %rax, %rdi
callq 0x72e0
movq 0xc0(%rsp), %rsi
movq %rax, %rdi
callq 0x7240
leaq 0x11043(%rip), %rsi     # 0x190c6
movq %rax, %rdi
callq 0x72e0
movq 0x90(%rsp), %rsi
movq %rax, %rdi
callq 0x7240
movq %rax, %rdi
callq 0x71a0
leaq 0x138(%rsp), %rdi
callq 0x7430
leaq 0x10fe4(%rip), %rdx     # 0x1909b
leaq 0xc8(%rsp), %rdi
movq %r15, %rsi
callq 0x9066
leaq 0xe8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
movq %r14, %rdx
callq 0x9047
leaq 0x1101e(%rip), %rdx     # 0x19104
movq %rsp, %rdi
leaq 0xe8(%rsp), %rsi
callq 0x9028
leaq 0x138(%rsp), %rdi
movq %rsp, %rsi
pushq $0x30
popq %rdx
callq 0x7190
movq %rsp, %rdi
callq 0x7180
leaq 0xe8(%rsp), %rdi
callq 0x7180
leaq 0xc8(%rsp), %rdi
callq 0x7180
leaq 0x10fde(%rip), %rsi     # 0x19110
leaq 0x138(%rsp), %rdi
callq 0x72e0
movq %rax, %rdi
callq 0x71a0
movq 0x80(%rsp), %r13
leaq 0x122c2(%rip), %r14     # 0x1a418
leaq 0x138(%rsp), %r15
leaq 0x10f61(%rip), %r12     # 0x190c6
cmpq %rbx, %r13
je 0x822b
movq %r15, %rdi
movq %r14, %rsi
callq 0x72e0
movslq 0x20(%r13), %rcx
movq 0x18(%rbp), %rdx
imulq $0xb8, %rcx, %rcx
leaq (%rdx,%rcx), %rsi
addq $0x58, %rsi
movq %rax, %rdi
callq 0x72c0
movq %rax, %rdi
movq %r14, %rsi
callq 0x72e0
movq %rax, %rdi
movq %r12, %rsi
callq 0x72e0
movq 0x50(%r13), %rsi
movq %rax, %rdi
callq 0x7240
movq %rax, %rdi
movq %r12, %rsi
callq 0x72e0
movslq 0x20(%r13), %rcx
movq 0x18(%rbp), %rdx
imulq $0xb8, %rcx, %rcx
movq 0x8(%rdx,%rcx), %rsi
subq (%rdx,%rcx), %rsi
sarq $0x4, %rsi
movq %rax, %rdi
callq 0x7240
movq %rax, %rdi
movq %r12, %rsi
callq 0x72e0
movslq 0x20(%r13), %rcx
movq 0x18(%rbp), %rdx
imulq $0xb8, %rcx, %rcx
leaq (%rdx,%rcx), %rsi
addq $0x38, %rsi
movq %rax, %rdi
callq 0x72c0
movq %rax, %rdi
callq 0x71a0
movq %r13, %rdi
callq 0x7250
movq %rax, %r13
jmp 0x8165
leaq 0x138(%rsp), %rdi
callq 0x7430
leaq 0x68(%rsp), %rdi
callq 0x9758
leaq 0x108(%rsp), %rdi
callq 0x97bc
leaq 0x50(%rsp), %rdi
callq 0xc268
leaq 0x138(%rsp), %rdi
callq 0x7450
leaq 0x98(%rsp), %rdi
callq 0x97d0
addq $0x338, %rsp            # imm = 0x338
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq %rsp, %rdi
callq 0x7180
jmp 0x8295
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x7180
jmp 0x82a7
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
jmp 0x82b9
jmp 0x82d5
movq %rax, %rbx
movq %rsp, %rdi
callq 0x7180
jmp 0x82d8
jmp 0x82d5
movq %rax, %rbx
jmp 0x8306
jmp 0x82d5
jmp 0x82d5
jmp 0x82d5
jmp 0x82d5
jmp 0x82d5
jmp 0x82d5
jmp 0x82d5
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x9758
leaq 0x108(%rsp), %rdi
callq 0x97bc
leaq 0x50(%rsp), %rdi
callq 0xc268
leaq 0x138(%rsp), %rdi
callq 0x7450
leaq 0x98(%rsp), %rdi
callq 0x97d0
movq %rbx, %rdi
callq 0x7550