// File: /workspace/github_c_makefile_star2_O2/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 0x50b3
movq %rsi, %r15
movq %rdi, %rbx
movq (%rdi), %rdi
movq 0x8(%rbx), %r14
cmpq %r14, %rdi
je 0x50dc
movq 0x10(%rbx), %rax
movq %r15, %rsi
movq %r14, %rdx
callq *%rax
xorl %r13d, %r13d
movq (%rbx), %rax
cmpq %rax, %r15
je 0x50ad
movq 0x20(%r15), %r12
cmpb $0x0, 0x8(%r12)
je 0x50ad
movq 0x20(%r12), %rsi
movq 0x10(%rsi), %rax
cmpq %rax, %r12
je 0x5015
cmpb $0x0, 0x8(%rax)
je 0x5031
movb %r13b, 0x8(%rax)
movb %r13b, 0x8(%r12)
jmp 0x5028
movq 0x18(%rsi), %rax
cmpb $0x0, 0x8(%rax)
je 0x503d
movb %r13b, 0x8(%r12)
movb %r13b, 0x8(%rax)
movb $0x1, 0x8(%rsi)
movq %rsi, %r15
jmp 0x4fda
cmpq 0x10(%r12), %r15
je 0x5049
movq %r12, %rax
jmp 0x5063
cmpq 0x18(%r12), %r15
je 0x507b
movq %r12, %rax
jmp 0x5095
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x5145
movq 0x20(%r12), %rax
movq 0x20(%rax), %rsi
movq %r12, %r15
movb $0x0, 0x8(%rax)
movb $0x1, 0x8(%rsi)
movq %rbx, %rdi
movq %r14, %rdx
callq 0x5102
jmp 0x4fda
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x5102
movq 0x20(%r12), %rax
movq 0x20(%rax), %rsi
movq %r12, %r15
movb $0x0, 0x8(%rax)
movb $0x1, 0x8(%rsi)
movq %rbx, %rdi
movq %r14, %rdx
callq 0x5145
jmp 0x4fda
movb $0x0, 0x8(%rax)
jmp 0x50f1
leaq 0x1d0a(%rip), %rsi      # 0x6dc4
leaq 0x1d50(%rip), %rdx      # 0x6e11
leaq 0x1d1a(%rip), %r8       # 0x6de2
pushq $0x4
popq %rdi
movl $0x136, %ecx            # imm = 0x136
xorl %eax, %eax
callq 0x4c60
pushq $-0x1
popq %rax
jmp 0x50f3
movq %r15, (%rbx)
movq %r14, 0x10(%r15)
movq %r14, 0x18(%r15)
andq $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