// File: /workspace/github_cpp_makefile_star2_O1/reddragon[P]packed-memory-array/impl1.cpp
// Function: PackedMemoryArray<int>::smallest_interval_in_balance(int, int*, int*) const
int PackedMemoryArray<E>::smallest_interval_in_balance(int index, int * node_index, int * node_level) const {
    // If we are trying to insert at the end of the PMA
    if (index == (int)store.size()) {
        index = (int)store.size() - 1;
    }

    int level = -1;
    int start = index;
    int end = index, count = 1;
    unsigned int sz = segment_size;
    bool found = false;
    do {
        // Get the boundaries of the next interval
        int left = start - (start % sz);
        int right = left + sz;

        // Count only the necessary parts
        for(int i = left; i < start; i++)
            if(ELEM_EXISTS_AT(i))
                count++;
        for(int i = end + 1; i <= right; i++)
            if(ELEM_EXISTS_AT(i))
                count++;
        
        start = left;
        end = right;

        ++level;
        bool is_balanced = !is_out_of_balance(count + 1, level);
        // std::cout << "Level: " << level << ", from " << left << " to " << right << ", having " << count+1 << ", elements, is balanced?: " << is_balanced << ", segment_size: " << smallest_window_size << std::endl;
        // Would be able to fit another element?
        if(is_balanced) {
            found = true;
            break;
        }
        sz <<= 1;
        
    } while(sz <= store.size());
    if(!found) {
        // We did not find a balanced interval
        *node_index = *node_level = -1;
        return -1;
    }

    *node_index = start;
    *node_level = level;
    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, 0x18(%rsp)
movq %rdx, 0x10(%rsp)
movabsq $-0x8000000000000000, %r15 # imm = 0x8000000000000000
movq 0x8(%rdi), %rax
subq (%rdi), %rax
sarq $0x2, %rax
leal -0x1(%rax), %ecx
movq %rax, 0x20(%rsp)
cmpl %esi, %eax
cmovnel %esi, %ecx
movq 0x18(%rdi), %r13
movl 0x5c(%rdi), %eax
movsd 0x40(%rdi), %xmm0
movsd %xmm0, 0x38(%rsp)
subsd 0x48(%rdi), %xmm0
movsd %xmm0, 0x30(%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0x54(%rdi), %xmm0
movsd %xmm0, 0x28(%rsp)
movl $0xffffffff, 0x4(%rsp)  # imm = 0xFFFFFFFF
xorl %r14d, %r14d
leaq 0x3f(%r15), %rbx
movl %ecx, %esi
movl $0x1, %r12d
movl %eax, 0x8(%rsp)
movl %eax, %ebp
movl %ecx, %r9d
movl %ecx, %eax
xorl %edx, %edx
divl %ebp
subl %edx, %r9d
cmpl %ecx, %r9d
jge 0x204c
movslq %r9d, %rax
movslq %ecx, %rcx
leaq 0x3f(%rax), %rdx
testq %rax, %rax
cmovnsq %rax, %rdx
sarq $0x6, %rdx
leaq (,%rdx,8), %rdx
addq %r13, %rdx
movq %rax, %rdi
andq %rbx, %rdi
xorl %r8d, %r8d
cmpq %r15, %rdi
setbe %r8b
movq -0x8(%rdx,%r8,8), %rdx
btq %rax, %rdx
adcl $0x0, %r12d
incq %rax
cmpq %rcx, %rax
jl 0x200d
leal (%r9,%rbp), %eax
cmpl %eax, %esi
movq %r9, 0x40(%rsp)
movl %eax, 0xc(%rsp)
jge 0x20a4
movslq %esi, %rcx
cltq
leaq 0x1(%rcx), %rdx
addq $0x40, %rcx
testq %rdx, %rdx
cmovnsq %rdx, %rcx
sarq $0x6, %rcx
leaq (,%rcx,8), %rcx
addq %r13, %rcx
movq %rdx, %rsi
andq %rbx, %rsi
xorl %edi, %edi
cmpq %r15, %rsi
setbe %dil
movq -0x8(%rcx,%rdi,8), %rcx
btq %rdx, %rcx
adcl $0x0, %r12d
movq %rdx, %rcx
cmpq %rax, %rdx
jl 0x2062
movl 0x4(%rsp), %ecx
incl %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
mulsd 0x30(%rsp), %xmm0
divsd 0x28(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movl 0x8(%rsp), %eax
movl %ecx, 0x4(%rsp)
shll %cl, %eax
subsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
mulsd %xmm1, %xmm0
callq 0x1150
cvttsd2si %xmm0, %eax
cmpl %eax, %r12d
setge %cl
shll %cl, %ebp
movzbl %r14b, %r14d
cmpl %eax, %r12d
movl $0x1, %eax
cmovll %eax, %r14d
movq 0x40(%rsp), %r9
jl 0x2116
movl %r9d, %ecx
movl 0xc(%rsp), %esi
cmpq %rbp, 0x20(%rsp)
jae 0x1ff9
testb $0x1, %r14b
je 0x2136
movq 0x10(%rsp), %rax
movl %r9d, (%rax)
movq 0x18(%rsp), %rax
movl 0x4(%rsp), %ecx
movl %ecx, (%rax)
movl $0x1, %eax
jmp 0x2149
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq 0x18(%rsp), %rcx
movl %eax, (%rcx)
movq 0x10(%rsp), %rcx
movl %eax, (%rcx)
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq