// File: readmapping[P]alfalfa/src/sparseSA.cpp
// Function: sparseSA::computeKmer()
void sparseSA::computeKmer() {
    stack<interval_t> intervalStack;
    stack<unsigned int> indexStack;
    
    interval_t curInterval(0,N/K-1,0);
    unsigned int curIndex = 0;
    unsigned int newIndex = 0;
    
    intervalStack.push(interval_t(0,N/K-1,0));
    indexStack.push(curIndex);
    
    while(!intervalStack.empty()){
        curInterval = intervalStack.top(); intervalStack.pop();
        curIndex = indexStack.top(); indexStack.pop();
        if(KMERSIZE == (long) (curInterval.depth)){
            if(curIndex < TABLESIZE){
                KMR[curIndex].left = curInterval.start;
                KMR[curIndex].right = curInterval.end;
            }
        }
        else{
            if(hasChild){//similar to function traverse_faster
                //walk up to depth KMERSIZE or new child
                long curLCP; //max LCP of this interval
                if (curInterval.start == curInterval.end)//BUGFIX: was omitted first and caused a bug
                    curLCP = N - SA[curInterval.start];
                else if (curInterval.start < CHILD[curInterval.end] && CHILD[curInterval.end] <= curInterval.end)
                    curLCP = LCP[CHILD[curInterval.end]];
                else
                    curLCP = LCP[CHILD[curInterval.start]];
                long minimum = min(curLCP,KMERSIZE);
                newIndex = curIndex;
                while(curInterval.depth < (long) minimum){
                    newIndex = (newIndex << 2) | BITADD[(unsigned char) S[SA[curInterval.start]+curInterval.depth]];
                    curInterval.depth ++;
                }
                if(curInterval.depth == KMERSIZE){//reached KMERSIZE in the middle of an edge
                    if(newIndex < TABLESIZE){
                        KMR[newIndex].left = curInterval.start;
                        KMR[newIndex].right = curInterval.end;
                    }
                }
                else{//find child intervals
                    long left = curInterval.start;
                    long right = CHILD[curInterval.end];
                    curIndex = newIndex;
                    if(curInterval.start >= right || right > curInterval.end)
                        right = CHILD[curInterval.start];
                    //now left and right point to first child
                    newIndex = (curIndex << 2) | BITADD[(unsigned char) S[SA[left]+curInterval.depth]];
                    if(newIndex < TABLESIZE){
                        intervalStack.push(interval_t(left,right-1,curInterval.depth+1));
                        indexStack.push(newIndex);
                    }
                    left = right;
                    //while has next L-index
                    while(CHILD[right] > right && LCP[right] == LCP[CHILD[right]]){
                        right = CHILD[right];
                        newIndex = (curIndex << 2) | BITADD[ (unsigned char) S[SA[left]+curInterval.depth]];
                        if(newIndex < TABLESIZE){
                            intervalStack.push(interval_t(left,right-1,curInterval.depth+1));
                            indexStack.push(newIndex);
                        }
                        left = right;
                    }
                    //last interval
                    newIndex = (curIndex << 2) | BITADD[ (unsigned char) S[SA[left]+curInterval.depth]];
                    if(newIndex < TABLESIZE){
                        intervalStack.push(interval_t(left,curInterval.end,curInterval.depth+1));
                        indexStack.push(newIndex);
                    }
                }
            }
            else{//similar to function traverse
                long start = curInterval.start; long end = curInterval.end;
                while(start <= curInterval.end){//bug: did not calculate correctly
                    newIndex = (curIndex << 2) | BITADD[ (unsigned char) S[SA[start]+curInterval.depth]];
                    start = curInterval.start;
                    end = curInterval.end;
                    top_down_faster(S[SA[start]+curInterval.depth], curInterval.depth, start, end);
                    if(newIndex < TABLESIZE){
                        intervalStack.push(interval_t(start,end,curInterval.depth+1));
                        indexStack.push(newIndex);
                    }
                    // Advance to next interval.
                    start = end+1; end = curInterval.end;
                }
            }
        }
    }
    
}

// Assembly:
subq $0x288, %rsp            # imm = 0x288
movq %rdi, 0x280(%rsp)
movq 0x280(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x230(%rsp), %rdi
callq 0x1ee40
leaq 0x1e0(%rsp), %rdi
callq 0x1ee70
jmp 0x17a9b
movq 0xf8(%rsp), %rcx
movq 0x38(%rcx), %rax
movq 0xe8(%rcx), %rcx
cqto
idivq %rcx
movq %rax, %rdx
decq %rdx
xorl %ecx, %ecx
movl %ecx, %esi
leaq 0x1b0(%rsp), %rdi
callq 0x1eea0
jmp 0x17acc
movq 0xf8(%rsp), %rcx
movl $0x0, 0x1ac(%rsp)
movl $0x0, 0x1a8(%rsp)
movq 0x38(%rcx), %rax
movq 0xe8(%rcx), %rcx
cqto
idivq %rcx
movq %rax, %rdx
decq %rdx
xorl %ecx, %ecx
movl %ecx, %esi
leaq 0x190(%rsp), %rdi
callq 0x1eea0
jmp 0x17b13
leaq 0x230(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0x1eee0
jmp 0x17b2a
leaq 0x1e0(%rsp), %rdi
leaq 0x1ac(%rsp), %rsi
callq 0x1ef10
jmp 0x17b41
jmp 0x17b43
leaq 0x230(%rsp), %rdi
callq 0x1ef40
movb %al, 0xf7(%rsp)
jmp 0x17b59
movb 0xf7(%rsp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x17b6b
jmp 0x185ab
leaq 0x230(%rsp), %rdi
callq 0x1ef60
movq %rax, 0xe8(%rsp)
jmp 0x17b82
movq 0xe8(%rsp), %rax
movl 0x10(%rax), %ecx
movl %ecx, 0x1c0(%rsp)
movups (%rax), %xmm0
movaps %xmm0, 0x1b0(%rsp)
leaq 0x230(%rsp), %rdi
callq 0x1ef70
jmp 0x17bae
leaq 0x1e0(%rsp), %rdi
callq 0x1ef80
movq %rax, 0xe0(%rsp)
jmp 0x17bc5
movq 0xe0(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x1ac(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x1ef90
jmp 0x17be5
movslq 0x1c0(%rsp), %rcx
movl $0xa, %eax
cmpq %rcx, %rax
jne 0x17cbf
movl 0x1ac(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x17cba
movq 0xf8(%rsp), %rdi
movq 0x1b0(%rsp), %rax
movl %eax, 0xd8(%rsp)
addq $0x100, %rdi            # imm = 0x100
movl 0x1ac(%rsp), %eax
movl %eax, %esi
callq 0x1efa0
movl 0xd8(%rsp), %ecx
movq 0xf8(%rsp), %rdi
movl %ecx, (%rax)
movq 0x1b8(%rsp), %rax
movl %eax, 0xdc(%rsp)
addq $0x100, %rdi            # imm = 0x100
movl 0x1ac(%rsp), %eax
movl %eax, %esi
callq 0x1efa0
movl 0xdc(%rsp), %ecx
movl %ecx, 0x4(%rax)
jmp 0x17cba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
jmp 0x185cd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1d8(%rsp)
movl %eax, 0x1d4(%rsp)
leaq 0x1e0(%rsp), %rdi
callq 0x1f3e0
jmp 0x185cd
jmp 0x185a6
movq 0xf8(%rsp), %rax
testb $0x1, 0xf0(%rax)
je 0x183da
movq 0x1b0(%rsp), %rax
cmpq 0x1b8(%rsp), %rax
jne 0x17d28
movq 0xf8(%rsp), %rdi
movq 0x38(%rdi), %rax
movq %rax, 0xd0(%rsp)
addq $0x70, %rdi
movq 0x1b0(%rsp), %rsi
callq 0x1ec60
movq %rax, %rcx
movq 0xd0(%rsp), %rax
movl (%rcx), %ecx
subq %rcx, %rax
movq %rax, 0x188(%rsp)
jmp 0x17e46
movq 0xf8(%rsp), %rdi
movq 0x1b0(%rsp), %rax
movq %rax, 0xc8(%rsp)
addq $0xd0, %rdi
movq 0x1b8(%rsp), %rsi
callq 0x1eb90
movq %rax, %rcx
movq 0xc8(%rsp), %rax
movslq (%rcx), %rcx
cmpq %rcx, %rax
jge 0x17ded
movq 0xf8(%rsp), %rdi
addq $0xd0, %rdi
movq 0x1b8(%rsp), %rsi
callq 0x1eb90
movslq (%rax), %rax
cmpq 0x1b8(%rsp), %rax
jg 0x17ded
movq 0xf8(%rsp), %rdi
movq %rdi, %rax
addq $0xa0, %rax
movq %rax, 0xb8(%rsp)
addq $0xd0, %rdi
movq 0x1b8(%rsp), %rsi
callq 0x1eb90
movq 0xb8(%rsp), %rdi
movslq (%rax), %rsi
callq 0x1ed20
movl %eax, 0xc4(%rsp)
jmp 0x17dda
movl 0xc4(%rsp), %eax
cltq
movq %rax, 0x188(%rsp)
jmp 0x17e44
movq 0xf8(%rsp), %rdi
movq %rdi, %rax
addq $0xa0, %rax
movq %rax, 0xa8(%rsp)
addq $0xd0, %rdi
movq 0x1b0(%rsp), %rsi
callq 0x1eb90
movq 0xa8(%rsp), %rdi
movslq (%rax), %rsi
callq 0x1ed20
movl %eax, 0xb4(%rsp)
jmp 0x17e33
movl 0xb4(%rsp), %eax
cltq
movq %rax, 0x188(%rsp)
jmp 0x17e46
leaq 0x655d3(%rip), %rsi     # 0x7d420
leaq 0x188(%rsp), %rdi
callq 0x1efc0
movq %rax, 0xa0(%rsp)
jmp 0x17e64
movq 0xa0(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x180(%rsp)
movl 0x1ac(%rsp), %eax
movl %eax, 0x1a8(%rsp)
movslq 0x1c0(%rsp), %rax
cmpq 0x180(%rsp), %rax
jge 0x17f33
movq 0xf8(%rsp), %rdi
movl 0x1a8(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x8c(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x90(%rsp)
addq $0x70, %rdi
movq 0x1b0(%rsp), %rsi
callq 0x1ec60
movq 0x90(%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x98(%rsp)
jmp 0x17ef8
movl 0x8c(%rsp), %eax
movq 0x98(%rsp), %rcx
movzbl (%rcx), %ecx
movl %ecx, %edx
leaq 0x6551d(%rip), %rcx     # 0x7d430
orl (%rcx,%rdx,4), %eax
movl %eax, 0x1a8(%rsp)
movl 0x1c0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c0(%rsp)
jmp 0x17e85
movslq 0x1c0(%rsp), %rax
cmpq $0xa, %rax
jne 0x17fc0
movl 0x1a8(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x17fbb
movq 0xf8(%rsp), %rdi
movq 0x1b0(%rsp), %rax
movl %eax, 0x84(%rsp)
addq $0x100, %rdi            # imm = 0x100
movl 0x1a8(%rsp), %eax
movl %eax, %esi
callq 0x1efa0
movl 0x84(%rsp), %ecx
movq 0xf8(%rsp), %rdi
movl %ecx, (%rax)
movq 0x1b8(%rsp), %rax
movl %eax, 0x88(%rsp)
addq $0x100, %rdi            # imm = 0x100
movl 0x1a8(%rsp), %eax
movl %eax, %esi
callq 0x1efa0
movl 0x88(%rsp), %ecx
movl %ecx, 0x4(%rax)
jmp 0x183d5
movq 0xf8(%rsp), %rdi
movq 0x1b0(%rsp), %rax
movq %rax, 0x178(%rsp)
addq $0xd0, %rdi
movq 0x1b8(%rsp), %rsi
callq 0x1eb90
movslq (%rax), %rax
movq %rax, 0x170(%rsp)
movl 0x1a8(%rsp), %eax
movl %eax, 0x1ac(%rsp)
movq 0x1b0(%rsp), %rax
cmpq 0x170(%rsp), %rax
jge 0x18029
movq 0x170(%rsp), %rax
cmpq 0x1b8(%rsp), %rax
jle 0x18050
movq 0xf8(%rsp), %rdi
addq $0xd0, %rdi
movq 0x1b0(%rsp), %rsi
callq 0x1eb90
movslq (%rax), %rax
movq %rax, 0x170(%rsp)
movq 0xf8(%rsp), %rdi
movl 0x1ac(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x6c(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x70(%rsp)
addq $0x70, %rdi
movq 0x178(%rsp), %rsi
callq 0x1ec60
movq 0x70(%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x78(%rsp)
jmp 0x180a1
movl 0x6c(%rsp), %eax
movq 0x78(%rsp), %rcx
movzbl (%rcx), %ecx
movl %ecx, %edx
leaq 0x6537a(%rip), %rcx     # 0x7d430
orl (%rcx,%rdx,4), %eax
movl %eax, 0x1a8(%rsp)
movl 0x1a8(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x1812a
movq 0x178(%rsp), %rsi
movq 0x170(%rsp), %rdx
decq %rdx
movl 0x1c0(%rsp), %ecx
incl %ecx
leaq 0x158(%rsp), %rdi
callq 0x1eea0
jmp 0x180fa
leaq 0x230(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x1eee0
jmp 0x18111
leaq 0x1e0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x1ef10
jmp 0x18128
jmp 0x1812a
movq 0x170(%rsp), %rax
movq %rax, 0x178(%rsp)
movq 0xf8(%rsp), %rdi
addq $0xd0, %rdi
movq 0x170(%rsp), %rsi
callq 0x1eb90
movslq (%rax), %rcx
xorl %eax, %eax
cmpq 0x170(%rsp), %rcx
movb %al, 0x6b(%rsp)
jle 0x181d9
movq 0xf8(%rsp), %rdi
addq $0xa0, %rdi
movq 0x170(%rsp), %rsi
callq 0x1ed20
movl %eax, 0x64(%rsp)
jmp 0x1818b
movq 0xf8(%rsp), %rdi
movq %rdi, %rax
addq $0xa0, %rax
movq %rax, 0x58(%rsp)
addq $0xd0, %rdi
movq 0x170(%rsp), %rsi
callq 0x1eb90
movq 0x58(%rsp), %rdi
movslq (%rax), %rsi
callq 0x1ed20
movl %eax, 0x60(%rsp)
jmp 0x181c8
movl 0x64(%rsp), %eax
movl 0x60(%rsp), %ecx
cmpl %ecx, %eax
sete %al
movb %al, 0x6b(%rsp)
movb 0x6b(%rsp), %al
testb $0x1, %al
jne 0x181e6
jmp 0x182fc
movq 0xf8(%rsp), %rdi
addq $0xd0, %rdi
movq 0x170(%rsp), %rsi
callq 0x1eb90
movq 0xf8(%rsp), %rdi
movslq (%rax), %rax
movq %rax, 0x170(%rsp)
movl 0x1ac(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x44(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x48(%rsp)
addq $0x70, %rdi
movq 0x178(%rsp), %rsi
callq 0x1ec60
movq 0x48(%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x50(%rsp)
jmp 0x1825e
movl 0x44(%rsp), %eax
movq 0x50(%rsp), %rcx
movzbl (%rcx), %ecx
movl %ecx, %edx
leaq 0x651bd(%rip), %rcx     # 0x7d430
orl (%rcx,%rdx,4), %eax
movl %eax, 0x1a8(%rsp)
movl 0x1a8(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x182e7
movq 0x178(%rsp), %rsi
movq 0x170(%rsp), %rdx
decq %rdx
movl 0x1c0(%rsp), %ecx
incl %ecx
leaq 0x140(%rsp), %rdi
callq 0x1eea0
jmp 0x182b7
leaq 0x230(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x1eee0
jmp 0x182ce
leaq 0x1e0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x1ef10
jmp 0x182e5
jmp 0x182e7
movq 0x170(%rsp), %rax
movq %rax, 0x178(%rsp)
jmp 0x1813a
movq 0xf8(%rsp), %rdi
movl 0x1ac(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x2c(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x30(%rsp)
addq $0x70, %rdi
movq 0x178(%rsp), %rsi
callq 0x1ec60
movq 0x30(%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x38(%rsp)
jmp 0x1834d
movl 0x2c(%rsp), %eax
movq 0x38(%rsp), %rcx
movzbl (%rcx), %ecx
movl %ecx, %edx
leaq 0x650ce(%rip), %rcx     # 0x7d430
orl (%rcx,%rdx,4), %eax
movl %eax, 0x1a8(%rsp)
movl 0x1a8(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x183d3
movq 0x178(%rsp), %rsi
movq 0x1b8(%rsp), %rdx
movl 0x1c0(%rsp), %ecx
incl %ecx
leaq 0x128(%rsp), %rdi
callq 0x1eea0
jmp 0x183a3
leaq 0x230(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x1eee0
jmp 0x183ba
leaq 0x1e0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x1ef10
jmp 0x183d1
jmp 0x183d3
jmp 0x183d5
jmp 0x185a4
movq 0x1b0(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x120(%rsp), %rax
cmpq 0x1b8(%rsp), %rax
jg 0x185a2
movq 0xf8(%rsp), %rdi
movl 0x1ac(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x14(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x18(%rsp)
addq $0x70, %rdi
movq 0x120(%rsp), %rsi
callq 0x1ec60
movq 0x18(%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x20(%rsp)
jmp 0x18461
movq 0xf8(%rsp), %rdi
movl 0x14(%rsp), %eax
movq 0x20(%rsp), %rcx
movzbl (%rcx), %ecx
movl %ecx, %edx
leaq 0x64fb2(%rip), %rcx     # 0x7d430
movl (%rcx,%rdx,4), %ecx
orl %ecx, %eax
movl %eax, 0x1a8(%rsp)
movq 0x1b0(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x118(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, (%rsp)
addq $0x70, %rdi
movq 0x120(%rsp), %rsi
callq 0x1ec60
movq (%rsp), %rdi
movl (%rax), %eax
movl 0x1c0(%rsp), %ecx
addl %ecx, %eax
movl %eax, %esi
callq 0x8830
movq %rax, 0x8(%rsp)
jmp 0x184e3
movq 0xf8(%rsp), %rdi
movq 0x8(%rsp), %rax
movsbl (%rax), %esi
movslq 0x1c0(%rsp), %rdx
leaq 0x120(%rsp), %rcx
leaq 0x118(%rsp), %r8
callq 0x1f000
jmp 0x18512
movl 0x1a8(%rsp), %eax
cmpq $0x100000, %rax         # imm = 0x100000
jge 0x18579
movq 0x120(%rsp), %rsi
movq 0x118(%rsp), %rdx
movl 0x1c0(%rsp), %ecx
incl %ecx
leaq 0x100(%rsp), %rdi
callq 0x1eea0
jmp 0x18549
leaq 0x230(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x1eee0
jmp 0x18560
leaq 0x1e0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x1ef10
jmp 0x18577
jmp 0x18579
movq 0x118(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x120(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x118(%rsp)
jmp 0x183fa
jmp 0x185a4
jmp 0x185a6
jmp 0x17b43
leaq 0x1e0(%rsp), %rdi
callq 0x1f3e0
leaq 0x230(%rsp), %rdi
callq 0x1f3f0
addq $0x288, %rsp            # imm = 0x288
retq
leaq 0x230(%rsp), %rdi
callq 0x1f3f0
movq 0x1d8(%rsp), %rdi
callq 0x8730
nopw (%rax,%rax)