// File: JohnPapad[P]Mini-Search-Engine/trie.cpp
// Function: my_trie::insert_word(char*, unsigned int)
void my_trie::insert_word(char * word, unsigned int doc_id)
{ // inseting a word into the trie or updating its posting list if word is already contained
  // every orizontal list is sorted alphabetically
    node * parent_node = NULL; //will indicate the parent of the first node of an orizontal list
    node * start_node = first; //will indicate the first node of an orizontal list

    for(unsigned int i = 0; i < strlen(word); i++)
    { //iterating word letter by letter
        node * prev_temp = NULL;  // will be used for iterating an orizontal list
        node * temp = start_node; // will be used for iterating an orizontal list
        node * n = NULL;
        bool reallocate_parent_flag = 0;

        if(temp == NULL)
        { // a new orizontal list will be created
            n = create_node(word[i]);  //this will be its first node
            reallocate_parent_flag = 1;
        }
        else
        { // a orizontal list already exists
            while(1) //iterating the orizontal list
            {
                if(temp == NULL)
                { //we have iterated the whole list and no same letter has been found. new letter will be added at the end of the list
                    n = create_node(word[i]);
                    prev_temp->right = n;
                    break;
                }

                if(temp->ch == word[i])
                { // we have found a same letter
                    parent_node = temp;
                    start_node = temp->down; //we will continue looking downwards
                    break;
                }
                else if(temp->ch < word[i])
                {// keep searching the orizontal list
                    prev_temp = temp;
                    temp = temp->right;
                }
                else
                {// no same letter found so far and no same letter will be found in this orizontal list because it is sorted alphabetically
                 // and current letter is bigger than the inserting one
                    n = create_node(word[i]);
                    n->right = temp;

                    if(prev_temp == NULL) //adding new letter at the start of the orizontal list
                    {
                        reallocate_parent_flag = 1;
                    }
                    else //adding new letter in the middle of the orizontal list
                    {
                        prev_temp->right = n ;
                    }

                    break;
                }
            }
        }

        if(n != NULL)  // a new node has been created (a new letter has been added)
        { // checking if parent's node down pointer needs to be reallocated
            if (reallocate_parent_flag == 1)
            {
                if (parent_node != NULL)
                {
                    parent_node->down = n;
                }
                else
                {
                    first = n;
                }
            }

            trie_size++;
            parent_node = n;
            start_node = n->down; //NULL
        }
    }

    //all letters of the inserting word have been consumed
    if(parent_node->pl_ptr == NULL)
    { // if the last's letter node does not have an existing posting list (inserting word is not contained in the trie)
        parent_node->pl_ptr = new posting_list(); //create one
    }

    parent_node->pl_ptr->update(word, doc_id);  //inserting word already exists, therefore update its posting list

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq $0x0, -0x20(%rbp)
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2070
movq %rax, %rcx
movq -0x70(%rbp), %rax
cmpq %rcx, %rax
jae 0x4901
movq $0x0, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movb $0x0, -0x49(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x47c9
movq -0x68(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
movsbl (%rax,%rcx), %esi
callq 0x46d0
movq %rax, -0x48(%rbp)
movb $0x1, -0x49(%rbp)
jmp 0x489b
jmp 0x47cb
cmpq $0x0, -0x40(%rbp)
jne 0x47fb
movq -0x68(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
movsbl (%rax,%rcx), %esi
callq 0x46d0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x4899
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movq -0x10(%rbp), %rcx
movl -0x2c(%rbp), %edx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jne 0x4827
movq -0x40(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x4899
movq -0x40(%rbp), %rax
movsbl (%rax), %eax
movq -0x10(%rbp), %rcx
movl -0x2c(%rbp), %edx
movsbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jge 0x4853
movq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x4892
movq -0x68(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
movsbl (%rax,%rcx), %esi
callq 0x46d0
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x8(%rax)
cmpq $0x0, -0x38(%rbp)
jne 0x4884
movb $0x1, -0x49(%rbp)
jmp 0x4890
movq -0x48(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x4899
jmp 0x4894
jmp 0x47cb
jmp 0x489b
cmpq $0x0, -0x48(%rbp)
je 0x48f1
movb -0x49(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x48d2
cmpq $0x0, -0x20(%rbp)
je 0x48c4
movq -0x48(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x48d0
movq -0x68(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x48d2
movq -0x68(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x48(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x48f3
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x4765
movq -0x20(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x4951
movl $0x18, %edi
callq 0x20e0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x78(%rbp)
callq 0x4bd0
jmp 0x4927
movq -0x78(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x18(%rax)
jmp 0x4951
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x18, %esi
callq 0x20f0
jmp 0x496e
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
callq 0x4e70
addq $0x80, %rsp
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x2250
nopw (%rax,%rax)