// File: readmapping[P]alfalfa/src/sparseSA.cpp
// Function: sparseSA::construct()
void sparseSA::construct(){
    if(K > 1) {
        long bucketNr = 1;
        int *intSA = new int[N/K+1];  
        for(int i = 0; i < N/K; i++) intSA[i] = i; // Init SA.
        int* t_new = new int[N/K+1];
        long* BucketBegin = new long[256]; // array to save current bucket beginnings
        radixStep(t_new, intSA, bucketNr, BucketBegin, 0, N/K-1, 0); // start radix sort
        t_new[N/K] = 0; // Terminate new integer string.
        delete[] BucketBegin;

        // Suffix sort integer text.
        cerr << "# suffixsort()" << endl;
        suffixsort(t_new, intSA, N/K, bucketNr, 0);
        cerr << "# DONE suffixsort()" << endl;

        delete[] t_new;

        // Translate suffix array.
        SA.resize(N/K);
        for (long i=0; i<N/K; i++) SA[i] = (unsigned int)intSA[i+1] * K;
        delete[] intSA;

        // Build ISA using sparse SA.
        ISA.resize(N/K);
        for(long i = 0; i < N/K; i++) { ISA[SA[i]/K] = i; }
    }
    else {
        SA.resize(N);
        ISA.resize(N);
        int char2int[UCHAR_MAX+1]; // Map from char to integer alphabet.

        // Zero char2int mapping.
        for (int i=0; i<=UCHAR_MAX; i++) char2int[i]=0;

        // Determine which characters are used in the string S.
        for (long i = 0; i < N; i++) char2int[(int)S[i]]=1;

        // Count the size of the alphabet.
        int alphasz = 0;
        for(int i=0; i <= UCHAR_MAX; i++) {
        if (char2int[i]) char2int[i]=alphasz++;
        else char2int[i] = -1;
        }

        // Remap the alphabet.
        for(long i = 0; i < N; i++) ISA[i] = (int)S[i];
        for (long i = 0; i < N; i++) ISA[i]=char2int[ISA[i]] + 1;
        // First "character" equals 1 because of above plus one, l=1 in suffixsort().
        int alphalast = alphasz + 1;

        // Use LS algorithm to construct the suffix array.
        int *SAint = (int*)(&SA[0]);
        suffixsort(&ISA[0], SAint , N-1, alphalast, 1);
    }

    cerr << "size concatenated sequence = " << N << endl;

    LCP.resize(N/K);
    cerr << "number of suffix array values = " << N/K << endl;
    // Use algorithm by Kasai et al to construct LCP array.
    computeLCP();  // SA + ISA -> LCP
    LCP.init();
    if(!hasSufLink){
        {
          vector<int> tmp;
          ISA.swap(tmp);
        }
    }
    if(hasChild){
        CHILD.resize(N/K);
        //Use algorithm by Abouelhoda et al to construct CHILD array
        computeChild();
    }
    if(hasKmer){
        KMR.resize(TABLESIZE, saTuple_t());
        computeKmer();
    }

    NKm1 = N/K-1;
}

// Assembly:
subq $0x528, %rsp            # imm = 0x528
movq %rdi, 0x520(%rsp)
movq 0x520(%rsp), %rax
movq %rax, 0x80(%rsp)
cmpq $0x1, 0xe8(%rax)
jle 0x1a2c3
movq 0x80(%rsp), %rcx
movq $0x1, 0x518(%rsp)
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
addq $0x1, %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x8030
movq %rax, 0x510(%rsp)
movl $0x0, 0x50c(%rsp)
movq 0x80(%rsp), %rcx
movslq 0x50c(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rcx
movq 0x78(%rsp), %rax
cmpq %rcx, %rax
jge 0x19f82
movl 0x50c(%rsp), %edx
movq 0x510(%rsp), %rax
movslq 0x50c(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x50c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x50c(%rsp)
jmp 0x19f26
movq 0x80(%rsp), %rcx
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
addq $0x1, %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x8030
movq %rax, 0x500(%rsp)
movl $0x800, %edi            # imm = 0x800
callq 0x8030
movq 0x80(%rsp), %rdi
movq %rax, 0x4f8(%rsp)
movq 0x500(%rsp), %rsi
movq 0x510(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x4f8(%rsp), %r8
movq 0x38(%rdi), %rax
cqto
idivq 0xe8(%rdi)
movq 0x60(%rsp), %rdx
subq $0x1, %rax
leaq 0x518(%rsp), %rcx
xorl %r9d, %r9d
movq %rax, (%rsp)
movq $0x0, 0x8(%rsp)
callq 0x1a760
movq 0x80(%rsp), %rcx
movq 0x500(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rcx
movq 0x68(%rsp), %rax
movl $0x0, (%rax,%rcx,4)
movq 0x4f8(%rsp), %rax
movq %rax, 0x70(%rsp)
cmpq $0x0, %rax
je 0x1a07c
movq 0x70(%rsp), %rdi
callq 0x8520
movq 0x7cf6d(%rip), %rdi     # 0x96ff0
leaq 0x632b0(%rip), %rsi     # 0x7d33a
callq 0x8360
movq %rax, %rdi
movq 0x7cf17(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x80(%rsp), %rcx
movq 0x500(%rsp), %rdi
movq 0x510(%rsp), %rsi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movl %eax, %edx
movq 0x518(%rsp), %rax
movl %eax, %ecx
xorl %r8d, %r8d
callq 0x72260
movq 0x7cf12(%rip), %rdi     # 0x96ff0
leaq 0x63264(%rip), %rsi     # 0x7d349
callq 0x8360
movq %rax, %rdi
movq 0x7cebc(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x500(%rsp), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x1a116
movq 0x58(%rsp), %rdi
callq 0x8520
movq 0x80(%rsp), %rcx
movq %rcx, %rdi
addq $0x70, %rdi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x1f570
movq $0x0, 0x4f0(%rsp)
movq 0x80(%rsp), %rcx
movq 0x4f0(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rcx
movq 0x50(%rsp), %rax
cmpq %rcx, %rax
jge 0x1a1cd
movq 0x80(%rsp), %rdi
movq 0x510(%rsp), %rax
movq 0x4f0(%rsp), %rcx
movl 0x4(%rax,%rcx,4), %eax
imulq 0xe8(%rdi), %rax
movl %eax, 0x4c(%rsp)
addq $0x70, %rdi
movq 0x4f0(%rsp), %rsi
callq 0x1ec60
movl 0x4c(%rsp), %ecx
movl %ecx, (%rax)
movq 0x4f0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x4f0(%rsp)
jmp 0x1a146
movq 0x510(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, %rax
je 0x1a1ea
movq 0x40(%rsp), %rdi
callq 0x8520
movq 0x80(%rsp), %rcx
movq %rcx, %rdi
addq $0x88, %rdi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x1f750
movq $0x0, 0x4e8(%rsp)
movq 0x80(%rsp), %rcx
movq 0x4e8(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rcx
movq 0x38(%rsp), %rax
cmpq %rcx, %rax
jge 0x1a2be
movq 0x80(%rsp), %rdi
movq 0x4e8(%rsp), %rax
movl %eax, 0x34(%rsp)
movq %rdi, %rax
addq $0x88, %rax
movq %rax, 0x28(%rsp)
addq $0x70, %rdi
movq 0x4e8(%rsp), %rsi
callq 0x1ec60
movq 0x80(%rsp), %rcx
movq 0x28(%rsp), %rdi
movl (%rax), %eax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x1eb90
movl 0x34(%rsp), %ecx
movl %ecx, (%rax)
movq 0x4e8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x4e8(%rsp)
jmp 0x1a21d
jmp 0x1a58c
movq 0x80(%rsp), %rax
movq %rax, %rdi
addq $0x70, %rdi
movq 0x38(%rax), %rsi
callq 0x1f570
movq 0x80(%rsp), %rax
movq %rax, %rdi
addq $0x88, %rdi
movq 0x38(%rax), %rsi
callq 0x1f750
movl $0x0, 0xdc(%rsp)
cmpl $0xff, 0xdc(%rsp)
jg 0x1a334
movslq 0xdc(%rsp), %rax
movl $0x0, 0xe0(%rsp,%rax,4)
movl 0xdc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xdc(%rsp)
jmp 0x1a301
movq $0x0, 0xd0(%rsp)
movq 0x80(%rsp), %rcx
movq 0xd0(%rsp), %rax
cmpq 0x38(%rcx), %rax
jge 0x1a395
movq 0x80(%rsp), %rdi
addq $0x50, %rdi
movq 0xd0(%rsp), %rsi
callq 0x8830
movsbl (%rax), %eax
cltq
movl $0x1, 0xe0(%rsp,%rax,4)
movq 0xd0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xd0(%rsp)
jmp 0x1a340
movl $0x0, 0xcc(%rsp)
movl $0x0, 0xc8(%rsp)
cmpl $0xff, 0xc8(%rsp)
jg 0x1a416
movslq 0xc8(%rsp), %rax
cmpl $0x0, 0xe0(%rsp,%rax,4)
je 0x1a3ee
movl 0xcc(%rsp), %ecx
movl %ecx, %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
movslq 0xc8(%rsp), %rax
movl %ecx, 0xe0(%rsp,%rax,4)
jmp 0x1a401
movslq 0xc8(%rsp), %rax
movl $0xffffffff, 0xe0(%rsp,%rax,4) # imm = 0xFFFFFFFF
jmp 0x1a403
movl 0xc8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc8(%rsp)
jmp 0x1a3ab
movq $0x0, 0xc0(%rsp)
movq 0x80(%rsp), %rcx
movq 0xc0(%rsp), %rax
cmpq 0x38(%rcx), %rax
jge 0x1a490
movq 0x80(%rsp), %rdi
addq $0x50, %rdi
movq 0xc0(%rsp), %rsi
callq 0x8830
movq 0x80(%rsp), %rdi
movsbl (%rax), %eax
movl %eax, 0x24(%rsp)
addq $0x88, %rdi
movq 0xc0(%rsp), %rsi
callq 0x1eb90
movl 0x24(%rsp), %ecx
movl %ecx, (%rax)
movq 0xc0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xc0(%rsp)
jmp 0x1a422
movq $0x0, 0xb8(%rsp)
movq 0x80(%rsp), %rcx
movq 0xb8(%rsp), %rax
cmpq 0x38(%rcx), %rax
jge 0x1a517
movq 0x80(%rsp), %rdi
addq $0x88, %rdi
movq 0xb8(%rsp), %rsi
callq 0x1eb90
movq 0x80(%rsp), %rdi
movslq (%rax), %rax
movl 0xe0(%rsp,%rax,4), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
addq $0x88, %rdi
movq 0xb8(%rsp), %rsi
callq 0x1eb90
movl 0x20(%rsp), %ecx
movl %ecx, (%rax)
movq 0xb8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xb8(%rsp)
jmp 0x1a49c
movq 0x80(%rsp), %rdi
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xb4(%rsp)
addq $0x70, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1ec60
movq 0x80(%rsp), %rdi
movq %rax, 0xa8(%rsp)
addq $0x88, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1eb90
movq %rax, %rdi
movq 0x80(%rsp), %rax
movq 0xa8(%rsp), %rsi
movq 0x38(%rax), %rax
subq $0x1, %rax
movl %eax, %edx
movl 0xb4(%rsp), %ecx
movl $0x1, %r8d
callq 0x72260
movq 0x7ca5d(%rip), %rdi     # 0x96ff0
leaq 0x62dc3(%rip), %rsi     # 0x7d35d
callq 0x8360
movq %rax, %rdi
movq 0x80(%rsp), %rax
movq 0x38(%rax), %rsi
callq 0x8790
movq %rax, %rdi
movq 0x7c9f3(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x80(%rsp), %rcx
movq %rcx, %rdi
addq $0xa0, %rdi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x1f890
movq 0x7ca00(%rip), %rdi     # 0x96ff0
leaq 0x62d84(%rip), %rsi     # 0x7d37b
callq 0x8360
movq 0x80(%rsp), %rcx
movq %rax, %rdi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x8790
movq %rax, %rdi
movq 0x7c98a(%rip), %rsi     # 0x96fb0
callq 0x83b0
movq 0x80(%rsp), %rdi
callq 0x170d0
movq 0x80(%rsp), %rdi
addq $0xa0, %rdi
callq 0x16310
movq 0x80(%rsp), %rax
testb $0x1, 0xf1(%rax)
jne 0x1a693
leaq 0x90(%rsp), %rdi
callq 0xe760
movq 0x80(%rsp), %rdi
addq $0x88, %rdi
leaq 0x90(%rsp), %rsi
callq 0x1f8c0
leaq 0x90(%rsp), %rdi
callq 0xe770
movq 0x80(%rsp), %rax
testb $0x1, 0xf0(%rax)
je 0x1a6d8
movq 0x80(%rsp), %rcx
movq %rcx, %rdi
addq $0xd0, %rdi
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rsi
callq 0x1f750
movq 0x80(%rsp), %rdi
callq 0x17290
movq 0x80(%rsp), %rax
testb $0x1, 0xf8(%rax)
je 0x1a72d
movq 0x80(%rsp), %rax
addq $0x100, %rax            # imm = 0x100
movq %rax, 0x18(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x1f9e0
movq 0x18(%rsp), %rdi
movl $0x100000, %esi         # imm = 0x100000
leaq 0x88(%rsp), %rdx
callq 0x1f920
movq 0x80(%rsp), %rdi
callq 0x17a60
movq 0x80(%rsp), %rcx
movq 0x38(%rcx), %rax
cqto
idivq 0xe8(%rcx)
movq %rax, %rcx
movq 0x80(%rsp), %rax
subq $0x1, %rcx
movq %rcx, 0x48(%rax)
addq $0x528, %rsp            # imm = 0x528
retq
nopl (%rax)