// File: /workspace/github_cpp_makefile_star2_O1/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 0x2861
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq (%rdi), %r13
movq 0x48(%rbx), %r14
movq %r14, %rsi
callq 0x2e7a
movq %rax, %r12
movq 0x50(%rbx), %r15
movq %r15, %rsi
callq 0x2e7a
movq %r12, %rcx
subq %rax, %rcx
seta %dl
cmpq $0x2, %rcx
setae %cl
andb %dl, %cl
cmpb $0x1, %cl
jne 0x2734
movq 0x58(%rbx), %rax
movq %r13, %rcx
testq %rax, %rax
je 0x2771
cmpq %rbx, 0x50(%rax)
je 0x276d
cmpq %rbx, 0x48(%rax)
jne 0x2774
leaq 0x48(%rax), %rcx
jmp 0x2771
subq %r12, %rax
seta %cl
cmpq $0x2, %rax
setae %al
andb %cl, %al
cmpb $0x1, %al
jne 0x284b
movq 0x58(%rbx), %rax
movq %r13, %rcx
testq %rax, %rax
je 0x27db
cmpq %rbx, 0x50(%rax)
je 0x27d7
cmpq %rbx, 0x48(%rax)
jne 0x27de
leaq 0x48(%rax), %rcx
jmp 0x27db
leaq 0x50(%rax), %rcx
movq %r14, (%rcx)
movq %rax, 0x58(%r14)
movq %r14, 0x58(%rbx)
movq 0x50(%r14), %rax
movq %rax, 0x48(%rbx)
testq %rax, %rax
je 0x279a
movq %rbx, 0x58(%rax)
movq %rbx, 0x50(%r14)
movq 0x40(%rax), %rcx
incq %rcx
jmp 0x27a3
movq %rbx, 0x50(%r14)
movl $0x1, %ecx
movq 0x50(%rbx), %rax
testq %rax, %rax
je 0x27b2
movq 0x40(%rax), %rax
jmp 0x27b4
xorl %eax, %eax
addq %rcx, %rax
movq %rax, 0x40(%rbx)
movq 0x48(%r14), %rcx
testq %rcx, %rcx
je 0x27cd
movq 0x40(%rcx), %rcx
incq %rcx
jmp 0x27d2
movl $0x1, %ecx
addq %rax, %rcx
jmp 0x2844
leaq 0x50(%rax), %rcx
movq %r15, (%rcx)
movq %rax, 0x58(%r15)
movq %r15, 0x58(%rbx)
movq 0x48(%r15), %rcx
movq %rcx, 0x50(%rbx)
testq %rcx, %rcx
je 0x27f7
movq %rbx, 0x58(%rcx)
movq %rbx, 0x48(%r15)
movq 0x48(%rbx), %rax
testq %rax, %rax
je 0x280d
movq 0x40(%rax), %rax
incq %rax
jmp 0x2812
movl $0x1, %eax
testq %rcx, %rcx
je 0x281d
movq 0x40(%rcx), %rcx
jmp 0x281f
xorl %ecx, %ecx
leaq (%rcx,%rax), %rdx
movq %rdx, 0x40(%rbx)
movq 0x50(%r15), %rdx
testq %rdx, %rdx
je 0x2836
movq 0x40(%rdx), %rdx
jmp 0x2838
xorl %edx, %edx
addq %rax, %rcx
incq %rcx
addq %rdx, %rcx
movq %r15, %r14
movq %rcx, 0x40(%r14)
movq %r14, %rbx
movq 0x58(%rbx), %rbx
testq %rbx, %rbx
jne 0x26e4
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq