// File: /workspace/github_cpp_makefile_star2_O3/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
movq 0x18(%rdi), %r13
subq (%rdi), %rax
sarq $0x2, %rax
leal -0x1(%rax), %ecx
movq %rax, 0x20(%rsp)
cmpl %esi, %eax
cmovnel %esi, %ecx
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, %ebp       # imm = 0xFFFFFFFF
movl $0x1, %r14d
leaq 0x3f(%r15), %rbx
movl %ecx, %esi
movl %eax, 0x8(%rsp)
movl %eax, %r12d
movl %ecx, %r9d
movl %ecx, %eax
xorl %edx, %edx
divl %r12d
subl %edx, %r9d
cmpl %ecx, %r9d
jge 0x2033
movslq %r9d, %rax
movslq %ecx, %rcx
leal 0x3f(%rax), %edx
testl %eax, %eax
cmovnsl %eax, %edx
sarl $0x6, %edx
movslq %edx, %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, %r14d
incq %rax
cmpq %rcx, %rax
jl 0x1ff5
leal (%r9,%r12), %ecx
cmpl %ecx, %esi
movq %r9, 0x40(%rsp)
movl %ecx, 0xc(%rsp)
jge 0x208c
movslq %esi, %rax
movslq %ecx, %rcx
incl %esi
incq %rax
leal 0x3f(%rsi), %edx
testl %esi, %esi
cmovnsl %esi, %edx
sarl $0x6, %edx
movslq %edx, %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, %r14d
incl %esi
cmpq %rcx, %rax
jl 0x204c
incl %ebp
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
mulsd 0x30(%rsp), %xmm0
divsd 0x28(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
movl 0x8(%rsp), %eax
movl %ebp, %ecx
shll %cl, %eax
subsd %xmm0, %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
mulsd %xmm1, %xmm0
callq 0x1150
cvttsd2si %xmm0, %eax
cmpl %eax, %r14d
movq 0x40(%rsp), %r9
jl 0x20e8
addl %r12d, %r12d
movl %r9d, %ecx
movl 0xc(%rsp), %edx
movl %edx, %esi
cmpq %r12, 0x20(%rsp)
jae 0x1fe0
cmpl %eax, %r14d
jge 0x2103
movq 0x10(%rsp), %rax
movl %r9d, (%rax)
movq 0x18(%rsp), %rax
movl %ebp, (%rax)
movl $0x1, %eax
jmp 0x2116
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
nop