// File: /workspace/github_cpp_makefile_star2_O2/dvjdjvu[P]bntree/./src/bntree.cpp
// Function: bntree::balance(node_s*)
void bntree::balance(node_t *p) {
    if (!p) {
        return;
    }

    node_t *child = NULL;
    node_t *parent = NULL;
    uint64_t ld = 0;
    uint64_t rd = 0;

    for (;;) {
        ld = this->weight_to_depth(p->left);
        rd = this->weight_to_depth(p->right);

        if (ld > rd && ld - rd > 1) {
            // Правый поворот. 
            // Глубина левого поддерева больше, чем глубина правого

            child = p->left;
            parent = p->parent;

            if (parent) {
                if (parent->right == p) {
                    parent->right = child;
                } else if (parent->left == p) {
                    parent->left = child;
                }
            } else {
                this->tree->root = child;
            }
            child->parent = parent;
            p->parent = child;

            p->left = child->right;
            if (p->left) {
                p->left->parent = p;
            }

            child->right = p;

            p->weight = 1 + this->get_child_weight(p->left) + this->get_child_weight(p->right);
            child->weight = 1 + this->get_child_weight(child->left) + this->get_child_weight(child->right);
            
            p = child;
            //break;
        } else if (rd > ld && rd - ld > 1) {
            // Левый поворот. 
            // Глубина правого поддерева больше, чем глубина левого

            child = p->right;
            parent = p->parent;

            if (parent) {
                if (parent->right == p) {
                    parent->right = child;
                } else if (parent->left == p) {
                    parent->left = child;
                }
            } else {
                this->tree->root = child;
            }
            child->parent = parent;
            p->parent = child;

            p->right = child->left;
            if (p->right) {
                p->right->parent = p;
            }

            child->left = p;

            p->weight = 1 + this->get_child_weight(p->left) + this->get_child_weight(p->right);
            child->weight = 1 + this->get_child_weight(child->left) + this->get_child_weight(child->right);

            p = child;
            //break;
        }

        if (p->parent) {
            p = p->parent;
        } else {
            break;
        }
    }

    return;
}

// Assembly:
testq %rsi, %rsi
je 0x2789
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq (%rdi), %rbp
movq 0x48(%r14), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2cc2
movq %rax, %r13
movq 0x50(%r14), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2cc2
movq %r13, %rcx
subq %rax, %rcx
seta %dl
cmpq $0x2, %rcx
setae %cl
andb %dl, %cl
cmpb $0x1, %cl
jne 0x2667
movq 0x58(%r14), %rax
movq %rbp, %rcx
testq %rax, %rax
je 0x26a0
cmpq %r14, 0x50(%rax)
je 0x269c
cmpq %r14, 0x48(%rax)
jne 0x26a3
leaq 0x48(%rax), %rcx
jmp 0x26a0
subq %r13, %rax
seta %cl
cmpq $0x2, %rax
setae %al
andb %cl, %al
cmpb $0x1, %al
jne 0x276e
movq 0x58(%r14), %rax
movq %rbp, %rcx
testq %rax, %rax
je 0x26fe
cmpq %r14, 0x50(%rax)
je 0x26fa
cmpq %r14, 0x48(%rax)
jne 0x2701
leaq 0x48(%rax), %rcx
jmp 0x26fe
leaq 0x50(%rax), %rcx
movq %r15, (%rcx)
movq %rax, 0x58(%r15)
movq %r15, 0x58(%r14)
movq 0x50(%r15), %rcx
movq %rcx, 0x48(%r14)
pushq $0x1
popq %rax
testq %rcx, %rcx
je 0x26c6
movq %r14, 0x58(%rcx)
movq 0x40(%rcx), %rax
incq %rax
movq %r14, 0x50(%r15)
movq 0x50(%r14), %rcx
testq %rcx, %rcx
je 0x26d9
movq 0x40(%rcx), %rcx
jmp 0x26db
xorl %ecx, %ecx
addq %rax, %rcx
movq %rcx, 0x40(%r14)
movq 0x48(%r15), %rdx
pushq $0x1
popq %rax
testq %rdx, %rdx
je 0x26f5
movq 0x40(%rdx), %rax
incq %rax
addq %rcx, %rax
jmp 0x2767
leaq 0x50(%rax), %rcx
movq %r12, (%rcx)
movq %rax, 0x58(%r12)
movq %r12, 0x58(%r14)
movq 0x48(%r12), %rcx
movq %rcx, 0x50(%r14)
testq %rcx, %rcx
je 0x271c
movq %r14, 0x58(%rcx)
movq %r14, 0x48(%r12)
movq 0x48(%r14), %rdx
pushq $0x1
popq %rax
testq %rdx, %rdx
je 0x2734
movq 0x40(%rdx), %rax
incq %rax
testq %rcx, %rcx
je 0x273f
movq 0x40(%rcx), %rcx
jmp 0x2741
xorl %ecx, %ecx
leaq (%rcx,%rax), %rdx
movq %rdx, 0x40(%r14)
movq 0x50(%r12), %rdx
testq %rdx, %rdx
je 0x2759
movq 0x40(%rdx), %rdx
jmp 0x275b
xorl %edx, %edx
addq %rcx, %rax
incq %rax
addq %rdx, %rax
movq %r12, %r15
movq %rax, 0x40(%r15)
movq %r15, %r14
movq 0x58(%r14), %r14
testq %r14, %r14
jne 0x2611
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq