// File: /workspace/github_cpp_makefile_star2_O3/sjain12[P]CliqueCounting/Graph.cpp
// Function: Escape::CGraph::renameByDegreeOrder() const
CGraph CGraph::renameByDegreeOrder() const
{
    CGraph ret = newCGraph(nVertices, nEdges);
    Pair *deg_info = new Pair[nVertices];

    VertexIdx *mapping = new VertexIdx[nVertices];
    VertexIdx *inverse = new VertexIdx[nVertices];

    
    // Construct array of pairs, storing old vertex label and degree
    for (VertexIdx i=0; i < nVertices; i++)
    {
        deg_info[i].first = i;
        deg_info[i].second = offsets[i+1]-offsets[i];
    }

    // sort the pairs by degree (if degree is same, sort by old vertex label)
    std::sort(deg_info,deg_info+nVertices,Escape::pairCompareSecond);

    // Construct the mapping of old vertex label to new vertex label
    // So mapping[i] is what i is mapped to
    // And inverse[i] is what maps to i
    for (VertexIdx i=0; i < nVertices; i++)
    {
        mapping[deg_info[i].first] = i;
        inverse[i] = deg_info[i].first;
    }

    // Initialize offsets of output CGraph
    ret.offsets[0] = 0;
    EdgeIdx current = 0;


    // Loop over new vertices
    for (VertexIdx new_label=0; new_label < nVertices; new_label++)
    {
        VertexIdx old_label = inverse[new_label]; // corresponding old label for new vertices
        for (EdgeIdx pos = offsets[old_label]; pos < offsets[old_label+1]; pos++) // loop over neighbors of old label
        {
            VertexIdx old_nbr = nbors[pos];
            VertexIdx new_nbr = mapping[old_nbr]; //corresponding new neighbor
            ret.nbors[current] = new_nbr; // insert new neighbor in nbors of output
            current++;
        }
        ret.offsets[new_label+1] = current; // all neighbors of new_label have been added, so we set offset for new_label+1
    }

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq (%rsi), %rsi
movq 0x8(%r14), %rdx
movq %rdi, (%rsp)
callq 0x863b
movq (%r14), %rbx
movq %rbx, %rax
shrq $0x3c, %rax
movq %rbx, %rbp
shlq $0x4, %rbp
xorl %r12d, %r12d
negq %rax
movl $0x0, %edi
sbbq %rdi, %rdi
orq %rbp, %rdi
callq 0x3030
movq %rax, %r13
movq %rbx, %rax
shrq $0x3d, %rax
leaq (,%rbx,8), %rcx
negq %rax
sbbq %r12, %r12
orq %rcx, %r12
movq %r12, %rdi
callq 0x3030
movq %rax, %r15
movq %r12, %rdi
callq 0x3030
movq %rax, %r12
testq %rbx, %rbx
jle 0x8a3f
movq 0x10(%r14), %rax
movq (%rax), %rsi
leaq 0x8(%r13), %rcx
xorl %edx, %edx
movq %rdx, -0x8(%rcx)
movq 0x8(%rax,%rdx,8), %rdi
incq %rdx
movq %rdi, %r8
subq %rsi, %r8
movq %r8, (%rcx)
addq $0x10, %rcx
movq %rdi, %rsi
cmpq %rdx, %rbx
jne 0x8a1c
jmp 0x8a41
je 0x8a96
addq %r13, %rbp
bsrq %rbx, %rdx
xorl $0x3f, %edx
addl %edx, %edx
xorq $0x7e, %rdx
leaq -0x59c(%rip), %rbx      # 0x84bc
movq %r13, %rdi
movq %rbp, %rsi
movq %rbx, %rcx
callq 0x96f7
movq %r13, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x97c2
movq (%r14), %rax
testq %rax, %rax
jle 0x8a96
xorl %ecx, %ecx
movq (%r13), %rdx
movq %rcx, (%r15,%rdx,8)
movq %rdx, (%r12,%rcx,8)
incq %rcx
addq $0x10, %r13
cmpq %rcx, %rax
jne 0x8a7e
movq (%rsp), %rax
movq 0x10(%rax), %rbx
movq $0x0, (%rbx)
cmpq $0x0, (%r14)
jle 0x8aec
movq 0x10(%r14), %rcx
movq 0x18(%r14), %rdx
movq 0x18(%rax), %rsi
xorl %edi, %edi
xorl %r8d, %r8d
movq (%r12,%r8,8), %r9
movq (%rcx,%r9,8), %r10
cmpq 0x8(%rcx,%r9,8), %r10
jge 0x8adf
movq (%rdx,%r10,8), %r11
movq (%r15,%r11,8), %r11
movq %r11, (%rsi,%rdi,8)
incq %rdi
incq %r10
jmp 0x8ac4
movq %rdi, 0x8(%rbx,%r8,8)
incq %r8
cmpq (%r14), %r8
jl 0x8abc
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq