// File: /workspace/github_c_makefile_star2_O1/ttoobne[P]bohttpd/src/core/rbtree.c
// Function: rbtree_insert
int rbtree_insert(volatile rbtree_t* tree, rbtree_node_t* node) {
    rbtree_node_t** root;
    rbtree_node_t* nil;
    rbtree_node_t* uncle;

    if (tree == NULL) {
        log_error("rbtree ptr is NULL.");
        return -1;
    }

    root = (rbtree_node_t**)&(tree->root);
    nil = tree->nil;
    
    /* 如果红黑树为空 */
    if (*root == nil) {
        *root = node;
        node->left_son = nil;
        node->right_son = nil;
        node->parent = NULL;
        rbtree_dye_black(node);

        return 0;
    }
    
    tree->insert(*root, node, nil);

    /*
     * 红黑树的性质（引自维基百科）
     *  1.节点是红色或黑色。
     *  2.根是黑色。
     *  3.所有叶子都是黑色（叶子是NIL节点）。
     *  4.每个红色节点必须有两个黑色的子节点。（从每个叶子到根的所有路径上不能有两个连续的红色节点。）
     *  5.从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。
     */
    /* 以下的任何操作都不会破坏性质 5 ，但可能导致性质 4 被破坏 */

    /* 如果父亲节点是红色的则性质 4 依然没有满足 */
    while (node != *root && rbtree_is_red(node->parent)) {
        /* 此处父亲节点一定不是根 */
        /* 如果叔叔节点是祖父节点的右孩子 */
        if (node->parent == node->parent->parent->left_son) {
            uncle = node->parent->parent->right_son;

            /* 如果叔叔节点是红色的 */
            if (rbtree_is_red(uncle)) {
                /* 此处可能导致性质 4 被破坏，如果破坏需要继续向上维护 */
                /* case 1: 叔叔和父亲都是红色 */
                /* 将叔叔和父亲染黑，祖父染红，那么祖父可能使得性质破坏 */
                rbtree_dye_black(node->parent);
                rbtree_dye_black(uncle);
                rbtree_dye_red(node->parent->parent);
                node = node->parent->parent;
            } else {
                /* 此处完成后已经满足所有性质 */
                /* case 2: node 是父亲节点的右孩子 */
                /* 通过左旋转化为 case 3 */
                if (node == node->parent->right_son) {
                    node = node->parent;
                    rbtree_left_rotate(root, node, nil);
                }

                /* case 3: 父亲是红色，叔叔是黑色 */
                /* 将父亲染黑，祖父染红，在祖父处进行右旋 */
                rbtree_dye_black(node->parent);
                rbtree_dye_red(node->parent->parent);
                rbtree_right_rotate(root, node->parent->parent, nil);
                /* 至此已经满足所有性质 */
            }
        } else {
            /* 如果叔叔节点是祖父节点的左孩子 */
            uncle = node->parent->parent->left_son;
            /* 如果叔叔节点是红色的 */
            if (rbtree_is_red(uncle)) {
                /* 此处可能导致性质 4 被破坏，如果破坏需要继续向上维护 */
                /* case 4: 叔叔和父亲都是红色 */
                /* 将叔叔和父亲染黑，祖父染红，那么祖父可能使得性质破坏 */
                rbtree_dye_black(uncle);
                rbtree_dye_black(node->parent);
                rbtree_dye_red(node->parent->parent);
                node = node->parent->parent;
            } else {
                /* 此处完成后已经满足所有性质 */
                /* case 5: node 是父亲节点的左孩子 */
                /* 通过右旋转化为 case 6 */
                if (node == node->parent->left_son) {
                    node = node->parent;
                    rbtree_right_rotate(root, node, nil);
                }

                /* case 6: 父亲是红色，叔叔是黑色 */
                /* 将父亲染黑，祖父染红，在祖父处进行左旋 */
                rbtree_dye_black(node->parent);
                rbtree_dye_red(node->parent->parent);
                rbtree_left_rotate(root, node->parent->parent, nil);
            }
        }
    }

    /* 如果最后 node 到了根节点的位置 */
    rbtree_dye_black(*root);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x539f
movq %rsi, %r15
movq %rdi, %rbx
movq (%rdi), %rdi
movq 0x8(%rbx), %r14
cmpq %r14, %rdi
je 0x53cc
movq 0x10(%rbx), %rax
movq %r15, %rsi
movq %r14, %rdx
callq *%rax
movq (%rbx), %rcx
cmpq %r15, %rcx
je 0x5399
movq 0x20(%r15), %r12
cmpb $0x0, 0x8(%r12)
je 0x5399
leaq 0x8(%r12), %rax
xorl %r13d, %r13d
movq 0x20(%r12), %rcx
movq 0x10(%rcx), %rdx
cmpq %rdx, %r12
je 0x52fa
cmpb $0x0, 0x8(%rdx)
je 0x5314
movb %r13b, 0x8(%rdx)
movb %r13b, (%rax)
jmp 0x530b
movq 0x18(%rcx), %rdx
cmpb $0x0, 0x8(%rdx)
je 0x5349
movb %r13b, (%rax)
movb %r13b, 0x8(%rdx)
movb $0x1, 0x8(%rcx)
movq %rcx, %r15
jmp 0x537c
cmpq 0x10(%r12), %r15
jne 0x532c
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x543c
movq %r12, %r15
movq 0x20(%r15), %rax
movb $0x0, 0x8(%rax)
movq 0x20(%rax), %rsi
movb $0x1, 0x8(%rsi)
movq %rbx, %rdi
movq %r14, %rdx
callq 0x53f5
jmp 0x537c
cmpq 0x18(%r12), %r15
jne 0x5361
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x53f5
movq %r12, %r15
movq 0x20(%r15), %rax
movb $0x0, 0x8(%rax)
movq 0x20(%rax), %rsi
movb $0x1, 0x8(%rsi)
movq %rbx, %rdi
movq %r14, %rdx
callq 0x543c
movq (%rbx), %rcx
cmpq %rcx, %r15
je 0x5399
movq 0x20(%r15), %r12
leaq 0x8(%r12), %rax
cmpb $0x0, 0x8(%r12)
jne 0x52dd
movb $0x0, 0x8(%rcx)
jmp 0x53e4
leaq 0x2a1e(%rip), %rsi      # 0x7dc4
leaq 0x2a64(%rip), %rdx      # 0x7e11
leaq 0x2a2e(%rip), %r8       # 0x7de2
movl $0x4, %edi
movl $0x136, %ecx            # imm = 0x136
xorl %eax, %eax
callq 0x252a
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x53e6
movq %r15, (%rbx)
movq %r14, 0x10(%r15)
movq %r14, 0x18(%r15)
movq $0x0, 0x20(%r15)
movb $0x0, 0x8(%r15)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq