// File: /workspace/github_cpp_makefile_star2_O1/dvjdjvu[P]bntree/./src/bntree.cpp
// Function: bntree::erase(unsigned long)
void bntree::erase(uint64_t index) {

    if (index < 0 || index > this->size() - 1) {
        return;
    }

    node_t *search_node = this->tree->root;
    uint64_t index_node = this->get_child_weight(search_node->left);

    for (;;) {
        if (index == index_node) {
            if (this->erase_simple(search_node)) {
                // pass
            } else if (search_node->left && search_node->right) {
                // Самый сложный случай, удаляемый узел имеет 2-х детей.

                node_t *del_node = search_node;
                uint64_t _index;
                // Маленькая балансировка, если правый вес больше левого то удаляем через право
                // иначе через лево
                if (search_node->right->weight > search_node->left->weight) {
                    _index = index_node + 1;
                } else {
                    _index = index_node - 1;
                }

                // Ищем узел со следующим индексом.
                for (;;) {
                    if (_index == index_node) {
                        // Узел найден
                        break;
                    } else if (_index > index_node) {
                        search_node->weight--;
                        search_node = search_node->right;
                        index_node += (this->get_child_weight(search_node->left) + 1);
                    } else {
                        search_node->weight--;
                        search_node = search_node->left;
                        index_node -= (this->get_child_weight(search_node->right) + 1);
                    }
                }

                del_node->data = search_node->data;
                this->erase_simple(search_node);
            }

            this->node_free(search_node);

            return;
        } else if (index > index_node) {
            search_node->weight--;
            search_node = search_node->right;
            index_node += (this->get_child_weight(search_node->left) + 1);
        } else {
            search_node->weight--;
            search_node = search_node->left;
            index_node -= (this->get_child_weight(search_node->right) + 1);
        }
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq (%rdi), %rax
movq (%rax), %r14
testq %r14, %r14
je 0x2949
movq 0x40(%r14), %rax
decq %rax
jmp 0x2950
movq $-0x1, %rax
cmpq %rsi, %rax
jae 0x2961
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x48(%r14), %rax
testq %rax, %rax
je 0x2970
movq 0x40(%rax), %rax
jmp 0x2972
xorl %eax, %eax
cmpq %rsi, %rax
jne 0x297c
movq %rax, %r12
jmp 0x29cb
decq 0x40(%r14)
cmpq %rsi, %rax
jae 0x299b
movq 0x50(%r14), %r14
movq 0x48(%r14), %rcx
testq %rcx, %rcx
je 0x29b1
movq 0x40(%rcx), %r12
incq %r12
jmp 0x29c0
movq 0x48(%r14), %r14
movq 0x50(%r14), %rcx
testq %rcx, %rcx
je 0x29b9
movq 0x40(%rcx), %r12
notq %r12
jmp 0x29c0
movl $0x1, %r12d
jmp 0x29c0
movq $-0x1, %r12
addq %rax, %r12
movq %r12, %rax
cmpq %rsi, %r12
jne 0x297c
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2862
testb %al, %al
jne 0x2a83
movq 0x48(%r14), %rax
testq %rax, %rax
je 0x2a83
movq 0x50(%r14), %rcx
testq %rcx, %rcx
je 0x2a83
movq 0x40(%rax), %rdx
xorl %eax, %eax
cmpq 0x40(%rcx), %rdx
adcq $-0x1, %rax
orq $0x1, %rax
addq %r12, %rax
movq %r14, %r15
decq 0x40(%r15)
cmpq %r12, %rax
jbe 0x2a2f
movq 0x50(%r15), %r15
movq 0x48(%r15), %rcx
testq %rcx, %rcx
je 0x2a45
movq 0x40(%rcx), %rcx
incq %rcx
jmp 0x2a53
movq 0x48(%r15), %r15
movq 0x50(%r15), %rcx
testq %rcx, %rcx
je 0x2a4c
movq 0x40(%rcx), %rcx
notq %rcx
jmp 0x2a53
movl $0x1, %ecx
jmp 0x2a53
movq $-0x1, %rcx
addq %rcx, %r12
cmpq %r12, %rax
jne 0x2a10
movq %r14, %rdi
movq %r15, %rsi
callq 0x20b0
addq $0x20, %r14
leaq 0x20(%r15), %rsi
movq %r14, %rdi
callq 0x20b0
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2862
jmp 0x2a86
movq %r14, %r15
movq %r15, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2486
nop