// File: /workspace/github_c_makefile_star2_O3/OhYee[P]computer_application_programming_experiment/hash_search/array_search/../../utils/radix_tree/radix_tree_node.c
// Function: rtn_add
radix_tree_node *rtn_add(radix_tree_node *rtn, bits *value, int k,
                         boolean memory) {
    // int m = pow2(k);
    if (rtn == NULL) {
        // if add to null, then make node
        rtn = rtn_init(k);
        rtn->end_of_value = T;
        if (memory) {
            rtn->value =
                bits_init_with_minimum_bits(value, value->start, value->end);
        } else {
            rtn->value = value;
        }
        return rtn;
    }

    int              l_node = bits_len(rtn->value);
    int              l_value = bits_len(value);
    radix_tree_node *root = rtn;

    // get the prefix
    int prefix = bits_prefix(rtn->value, value, k);
    if (prefix == l_node && prefix == l_value) {
        // value is same as this node.

        // this node is same as the value
        rtn->end_of_value = T;
        return rtn;
    }

    if (prefix < l_node) {
        // node need split
        int key = rtn_get_child_key(rtn->value, prefix, k);

        root = rtn_init(k);
        root->value = bits_sub(rtn->value, 0, prefix);
        root->end_of_value = F;
        root->children[key] = rtn;
        rtn->value->start += prefix;
    }

    if (prefix < l_value) {
        // new value need split
        int key = rtn_get_child_key(value, prefix, k);
        value->start += prefix;
        root->children[key] = rtn_add(root->children[key], value, k, memory);
    }

    return root;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %ecx, %ebp
movl %edx, %r15d
movq %rsi, %r14
testq %rdi, %rdi
je 0x2ef5
movq %rdi, %rbx
movl %ebp, 0x4(%rsp)
movq 0x10(%rdi), %rdi
callq 0x19a2
movl %eax, %ebp
movq %r14, %rdi
callq 0x19a2
movl %eax, %r13d
movq 0x10(%rbx), %rdi
movq %r14, %rsi
movl %r15d, %edx
callq 0x19a9
movl %eax, %r12d
xorl %ebp, %eax
movl %r12d, %ecx
xorl %r13d, %ecx
orl %eax, %ecx
jne 0x2f2d
leaq 0x11cd(%rip), %rax      # 0x40b8
movl (%rax), %eax
movl %eax, 0x8(%rbx)
jmp 0x2fc1
movl %r15d, %edi
callq 0x2e47
movq %rax, %rbx
leaq 0x11b1(%rip), %rax      # 0x40b8
movl (%rax), %eax
movl %eax, 0x8(%rbx)
testl %ebp, %ebp
je 0x2fbd
movl 0x8(%r14), %esi
movl 0xc(%r14), %edx
movq %r14, %rdi
callq 0x1841
movq %rax, 0x10(%rbx)
jmp 0x2fc1
cmpl %ebp, %r12d
jge 0x2f84
movq 0x10(%rbx), %rdi
movl %r12d, %esi
movl %r15d, %edx
callq 0x2dc6
movl %eax, (%rsp)
movl %r15d, %edi
callq 0x2e47
movq %rax, %rbp
movq 0x10(%rbx), %rdi
xorl %esi, %esi
movl %r12d, %edx
callq 0x18f9
movq %rax, 0x10(%rbp)
leaq 0x1154(%rip), %rax      # 0x40bc
movl (%rax), %eax
movl %eax, 0x8(%rbp)
movq (%rbp), %rax
movslq (%rsp), %rcx
movq %rbx, (%rax,%rcx,8)
movq 0x10(%rbx), %rax
addl %r12d, 0x8(%rax)
movq %rbp, %rbx
cmpl %r13d, %r12d
jge 0x2fc1
movq %r14, %rdi
movl %r12d, %esi
movl %r15d, %edx
callq 0x2dc6
addl %r12d, 0x8(%r14)
movq (%rbx), %rcx
movslq %eax, %r12
movq (%rcx,%r12,8), %rdi
movq %r14, %rsi
movl %r15d, %edx
movl 0x4(%rsp), %ecx
callq 0x2e91
movq (%rbx), %rcx
movq %rax, (%rcx,%r12,8)
jmp 0x2fc1
movq %r14, 0x10(%rbx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq