// File: /workspace/github_c_makefile_star2_O0/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
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x6b09
movl $0x4, %edi
leaq 0x32ea(%rip), %rsi      # 0x9dcd
leaq 0x3330(%rip), %rdx      # 0x9e1a
movl $0x136, %ecx            # imm = 0x136
leaq 0x32f5(%rip), %r8       # 0x9deb
movb $0x0, %al
callq 0x6450
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x6d65
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
cmpq -0x28(%rbp), %rax
jne 0x6b6d
movq -0x18(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x28(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x18(%rbp), %rax
movb $0x0, 0x8(%rax)
movl $0x0, -0x4(%rbp)
jmp 0x6d65
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq *%rax
movq -0x18(%rbp), %rcx
movq -0x20(%rbp), %rdx
xorl %eax, %eax
cmpq (%rdx), %rcx
movb %al, -0x31(%rbp)
je 0x6bad
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movzbl 0x8(%rax), %eax
cmpl $0x0, %eax
setne %al
movb %al, -0x31(%rbp)
movb -0x31(%rbp), %al
testb $0x1, %al
jne 0x6bb9
jmp 0x6d53
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x18(%rbp), %rcx
movq 0x20(%rcx), %rcx
movq 0x20(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jne 0x6c94
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpb $0x0, 0x8(%rax)
je 0x6c2b
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movb $0x0, 0x8(%rax)
movq -0x30(%rbp), %rax
movb $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movb $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x6c8f
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x20(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jne 0x6c5a
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x6d70
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movb $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movb $0x1, 0x8(%rax)
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rsi
movq -0x28(%rbp), %rdx
callq 0x6e40
jmp 0x6d4e
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpb $0x0, 0x8(%rax)
je 0x6ce8
movq -0x30(%rbp), %rax
movb $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movb $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movb $0x1, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x6d4c
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x20(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jne 0x6d17
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x6e40
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movb $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movb $0x1, 0x8(%rax)
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rsi
movq -0x28(%rbp), %rdx
callq 0x6d70
jmp 0x6d4e
jmp 0x6b86
movq -0x20(%rbp), %rax
movq (%rax), %rax
movb $0x0, 0x8(%rax)
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nop