// File: reddragon[P]packed-memory-array/impl1.cpp
// Function: PackedMemoryArray<int>::rebalance(int, int, int)
void PackedMemoryArray<E>::rebalance(int index, int level, E e) {
#ifndef OPTIMZE
    assert(level <= l);
#endif
    int c = CAPACITY_AT(level);
    // Move all the elements to one side
    int last = index + c - 1, count = 0;
    bool element_inserted = false;
    std::vector<E> level_copy;
    for(int i = last; i >= index; i--) {
        if(ELEM_EXISTS_AT(i)) {
            if(!element_inserted && store[i] < e) {
                level_copy.push_back(e);
                element_inserted = true;
            }
            level_copy.push_back(store[i]);
            delete_element_at(i);
            --last;
            count++;
        }
    }

    if(!element_inserted)
        level_copy.push_back(e);

    // Now copy
    double k = (c*1.0)/(level_copy.size()), p = 0;
    int correct_index;
    for(int i = level_copy.size()-1; i >= 0; i--) {
        p += k;
        // Now insert the element at the right position
        correct_index = index + (int)p - 1;
        insert_element_at(level_copy[i], correct_index);
    } 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movq -0x8(%rbp), %rcx
movq %rcx, -0x88(%rbp)
movl -0x10(%rbp), %eax
cmpl 0x54(%rcx), %eax
jg 0x51ed
jmp 0x520c
leaq 0x1ea2(%rip), %rdi      # 0x7096
leaq 0x1ea6(%rip), %rsi      # 0x70a1
movl $0x185, %edx            # imm = 0x185
leaq 0x1ea4(%rip), %rcx      # 0x70ab
callq 0x1090
movq -0x88(%rbp), %rax
movl 0x5c(%rax), %eax
movl -0x10(%rbp), %ecx
shll %cl, %eax
movl %eax, -0x18(%rbp)
movl -0xc(%rbp), %eax
addl -0x18(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movb $0x0, -0x21(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x16f0
movl -0x1c(%rbp), %eax
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0xc(%rbp), %eax
jl 0x5339
movq -0x88(%rbp), %rdi
addq $0x18, %rdi
movslq -0x44(%rbp), %rsi
callq 0x4750
movq %rdx, -0x98(%rbp)
movq %rax, -0x90(%rbp)
jmp 0x5274
movq -0x98(%rbp), %rax
movq -0x90(%rbp), %rcx
movq %rcx, -0x58(%rbp)
movq %rax, -0x50(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x38e0
testb $0x1, %al
jne 0x529c
jmp 0x5329
testb $0x1, -0x21(%rbp)
jne 0x52e8
movq -0x88(%rbp), %rdi
movslq -0x44(%rbp), %rsi
callq 0x4730
movl (%rax), %eax
cmpl -0x14(%rbp), %eax
jge 0x52e8
leaq -0x40(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x64a0
jmp 0x52c8
movb $0x1, -0x21(%rbp)
jmp 0x52e8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x1990
jmp 0x5421
movq -0x88(%rbp), %rdi
movslq -0x44(%rbp), %rsi
callq 0x4730
movq %rax, %rsi
leaq -0x40(%rbp), %rdi
callq 0x64a0
jmp 0x5306
movq -0x88(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x6510
jmp 0x5317
movl -0x1c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x532b
movl -0x44(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x5244
testb $0x1, -0x21(%rbp)
jne 0x5350
leaq -0x40(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x64a0
jmp 0x534e
jmp 0x5350
cvtsi2sdl -0x18(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x1950
movsd -0xa0(%rbp), %xmm0
movq %rax, %xmm1
movaps 0x1cb6(%rip), %xmm2     # 0x7030
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x1cba(%rip), %xmm2     # 0x7040
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x70(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x78(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x1950
subq $0x1, %rax
movl %eax, -0x80(%rbp)
cmpl $0x0, -0x80(%rbp)
jl 0x540f
movsd -0x70(%rbp), %xmm1
movsd -0x78(%rbp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x78(%rbp)
movl -0xc(%rbp), %edx
cvttsd2si -0x78(%rbp), %eax
movl %eax, %ecx
movl %edx, %eax
leal -0x1(%rax,%rcx), %eax
movl %eax, -0x7c(%rbp)
movslq -0x80(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x4730
movq -0x88(%rbp), %rdi
movl (%rax), %esi
movl -0x7c(%rbp), %edx
callq 0x18e0
jmp 0x5402
jmp 0x5404
movl -0x80(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x53b6
leaq -0x40(%rbp), %rdi
callq 0x1990
addq $0xa0, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x1170
nopw (%rax,%rax)