// File: MITRECND[P]snugglefish/src/nGramSearch.cpp
// Function: snugglefish::nGramSearch::searchAlpha(snugglefish::indexSet*, std::__cxx11::list<std::pair<unsigned long, unsigned long>, std::allocator<std::pair<unsigned long, unsigned long>>>&)
list<ngram_t_fidtype> nGramSearch::searchAlpha(indexSet* index, list< pair<uint64_t,size_t> > &queryList){
    list<ngram_t_fidtype> matchedIds;

    if(queryList.size() == 0){
        return matchedIds;
    }
    // this gets the ngram list for the first file, and places them 
    // into the matchedIds list
    ngram_t_numfiles count = 0;
    ngram_t_fidtype* ngrams = index->getNGrams((uint64_t) queryList.front().first, (size_t*) &count);
    for (ngram_t_numfiles j = 0; j < count; j++){
        matchedIds.push_back(ngrams[j]);
    }
        
    //Dont need the front element anymore so get rid of it
    queryList.pop_front();

    //For every id see if it's in the remaining Ngrams
    //Now for every subsequent NGram whittle down the list
    for(list< pair<uint64_t, size_t> >::iterator it = queryList.begin();
            it != queryList.end(); it++){

        ngram_t_numfiles ngram_elements = 0;
        ngram_t_fidtype* ngrams = index->getNGrams((uint64_t) (*it).first, (size_t*) &ngram_elements);
        uint32_t ngram_index = 0;

        list<ngram_t_fidtype>::iterator ft = matchedIds.begin();
        while(ft != matchedIds.end()){
            bool found = false;
            // Checks each element of the next fid array for
            // the current fid in matchedIds
            while(ngram_index < ngram_elements){
                if (ngrams[ngram_index] == (*ft)){
                    found = true;
                    break;
                }else if(ngrams[ngram_index] > (*ft)){
                    //update ngram location
                    // If the fid is too large, it is
                    // necessary to recheck the same index on the
                    // next pass, as to make sure it isn't missed
                    break;
                }
                ngram_index++;
            }

            if(!found){
                ft = matchedIds.erase(ft);
            }else{
                // ft++ is only needed if erase isn't called as 
                // erase moves the iterator ahead
                ft++;
            }
        }
    }

    return matchedIds;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rdi, -0xb0(%rbp)
movq %rdi, %rax
movq %rax, -0xa8(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movb $0x0, -0x19(%rbp)
callq 0x13ae0
movq -0x18(%rbp), %rdi
callq 0x13b00
cmpq $0x0, %rax
jne 0x13430
movb $0x1, -0x19(%rbp)
movl $0x1, -0x20(%rbp)
jmp 0x13661
movl $0x0, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x13b30
movq -0xc0(%rbp), %rdi
movq (%rax), %rsi
leaq -0x24(%rbp), %rdx
callq 0x191a0
movq %rax, -0xb8(%rbp)
jmp 0x13467
movq -0xb8(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x134c4
movq -0xb0(%rbp), %rdi
movq -0x30(%rbp), %rax
movl -0x40(%rbp), %ecx
leaq (%rax,%rcx,4), %rsi
callq 0x13b60
jmp 0x1349a
jmp 0x1349c
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x13479
movq -0xb0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x13860
jmp 0x13683
movq -0x18(%rbp), %rdi
callq 0x13ba0
movq -0x18(%rbp), %rdi
callq 0x13970
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
callq 0x139d0
movq %rax, -0x50(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x139a0
testb $0x1, %al
jne 0x134fd
jmp 0x13656
movl $0x0, -0x54(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xd0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x13a00
movq -0xd0(%rbp), %rdi
movq (%rax), %rsi
leaq -0x54(%rbp), %rdx
callq 0x191a0
movq %rax, -0xc8(%rbp)
jmp 0x13534
movq -0xb0(%rbp), %rdi
movq -0xc8(%rbp), %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
callq 0x13780
movq %rax, -0x70(%rbp)
movq -0xb0(%rbp), %rdi
callq 0x137e0
movq %rax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x137b0
testb $0x1, %al
jne 0x1357c
jmp 0x1363d
movb $0x0, -0x79(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x54(%rbp), %eax
jae 0x135e9
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xd4(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x13810
movq %rax, %rcx
movl -0xd4(%rbp), %eax
cmpl (%rcx), %eax
jne 0x135b4
movb $0x1, -0x79(%rbp)
jmp 0x135e9
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0xd8(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x13810
movq %rax, %rcx
movl -0xd8(%rbp), %eax
cmpl (%rcx), %eax
jbe 0x135dc
jmp 0x135e9
jmp 0x135de
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x13580
testb $0x1, -0x79(%rbp)
jne 0x13626
leaq -0x90(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x13c20
movq -0xb0(%rbp), %rdi
movq -0x90(%rbp), %rsi
callq 0x13bd0
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x70(%rbp)
jmp 0x13638
leaq -0x70(%rbp), %rdi
xorl %esi, %esi
callq 0x13830
movq %rax, -0x98(%rbp)
jmp 0x13556
jmp 0x1363f
leaq -0x48(%rbp), %rdi
xorl %esi, %esi
callq 0x13a80
movq %rax, -0xa0(%rbp)
jmp 0x134da
movb $0x1, -0x19(%rbp)
movl $0x1, -0x20(%rbp)
testb $0x1, -0x19(%rbp)
jne 0x13673
movq -0xb0(%rbp), %rdi
callq 0x13860
movq -0xa8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
movq -0x38(%rbp), %rdi
callq 0xe5d0
nopl (%rax)