// File: /workspace/github_cpp_makefile_star2_O3/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x408, %rsp            # imm = 0x408
movq %rdi, %rbx
movq 0xe8(%rdi), %rcx
cmpq $0x2, %rcx
jl 0x12be8
movq $0x1, (%rsp)
movq 0x38(%rbx), %rax
cqto
idivq %rcx
movq %rax, %r12
leaq 0x1(%rax), %r13
movq %r13, %rax
shrq $0x3e, %rax
leaq 0x4(,%r12,4), %rcx
xorl %r15d, %r15d
negq %rax
sbbq %r15, %r15
orq %rcx, %r15
movq %r15, %rdi
callq 0x7030
movq %rax, %r14
testq %r12, %r12
jle 0x12a33
andq $-0x2, %r13
leaq -0x1(%r12), %rax
movq %rax, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
movdqa 0x3188f(%rip), %xmm1    # 0x44250
xorl %eax, %eax
movdqa 0x2d675(%rip), %xmm2    # 0x40040
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x31885(%rip), %xmm4    # 0x44260
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %ecx
notl %ecx
testb $0x1, %cl
je 0x12a10
movl %eax, (%r14,%rax,4)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %ecx
testb $0x1, %cl
je 0x12a26
leal 0x1(%rax), %ecx
movl %ecx, 0x4(%r14,%rax,4)
addq $0x2, %rax
paddq %xmm4, %xmm1
cmpq %rax, %r13
jne 0x129db
movq %r15, %rdi
callq 0x7030
movq %rax, %r15
movl $0x800, %edi            # imm = 0x800
callq 0x7030
movq %rax, %rbp
decq %r12
movq %rsp, %r13
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
movq %r13, %rcx
movq %rax, %r8
xorl %r9d, %r9d
pushq $0x0
pushq %r12
callq 0x12e48
addq $0x10, %rsp
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movl $0x0, (%r15,%rax,4)
movq %rbp, %rdi
callq 0x7400
movq 0x41554(%rip), %r12     # 0x53fe8
leaq 0x3188f(%rip), %rsi     # 0x4432a
movl $0xe, %edx
movq %r12, %rdi
callq 0x7340
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x72b0
movsbl %al, %esi
movq %r12, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x71d0
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movl (%r13), %ecx
movq %r15, %rdi
movq %r14, %rsi
movl %eax, %edx
xorl %r8d, %r8d
callq 0x3e184
leaq 0x31841(%rip), %rsi     # 0x44339
movl $0x13, %edx
movq %r12, %rdi
callq 0x7340
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x72b0
movsbl %al, %esi
movq %r12, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x71d0
movq %r15, %rdi
callq 0x7400
leaq 0x70(%rbx), %r15
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movq %r15, %rdi
movq %rax, %rsi
callq 0x15a5e
movq 0x38(%rbx), %rax
movq 0xe8(%rbx), %rcx
cqto
idivq %rcx
testq %rax, %rax
jle 0x12b82
movq (%r15), %rdx
xorl %esi, %esi
movl 0x4(%r14,%rsi,4), %edi
imull %ecx, %edi
movl %edi, (%rdx,%rsi,4)
leaq 0x1(%rsi), %rdi
movq %rdi, %rsi
cmpq %rdi, %rax
jne 0x12b6b
movq %r14, %rdi
callq 0x7400
leaq 0x88(%rbx), %r14
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movq %r14, %rdi
movq %rax, %rsi
callq 0x15af0
movq 0x38(%rbx), %rax
movq 0xe8(%rbx), %rsi
cqto
idivq %rsi
testq %rax, %rax
jle 0x12cb8
movq %rax, %rcx
movq (%r15), %rdi
movq (%r14), %r8
xorl %r9d, %r9d
movl (%rdi,%r9,4), %eax
xorl %edx, %edx
idivq %rsi
movl %r9d, (%r8,%rax,4)
incq %r9
cmpq %r9, %rcx
jne 0x12bce
jmp 0x12cb8
leaq 0x70(%rbx), %r14
movq 0x38(%rbx), %rsi
movq %r14, %rdi
callq 0x15a5e
leaq 0x88(%rbx), %r12
movq 0x38(%rbx), %rsi
movq %r12, %rdi
callq 0x15af0
movq %rsp, %rdi
xorl %r15d, %r15d
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x7180
movq 0x38(%rbx), %rdx
testq %rdx, %rdx
jle 0x12c40
movq 0x50(%rbx), %rax
xorl %ecx, %ecx
movsbq (%rax,%rcx), %rsi
movl $0x1, (%rsp,%rsi,4)
incq %rcx
cmpq %rcx, %rdx
jne 0x12c2c
xorl %eax, %eax
movl (%rsp,%rax,4), %ecx
cmpl $0x1, %ecx
movl $0x0, %esi
sbbl %esi, %esi
movl %r15d, %edi
cmpl $0x1, %ecx
sbbl $-0x1, %r15d
orl %edi, %esi
movl %esi, (%rsp,%rax,4)
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x12c42
movq (%r12), %rdi
testq %rdx, %rdx
jle 0x12ca2
movq 0x50(%rbx), %rax
xorl %ecx, %ecx
movsbl (%rax,%rcx), %esi
movl %esi, (%rdi,%rcx,4)
incq %rcx
cmpq %rcx, %rdx
jne 0x12c78
testq %rdx, %rdx
jle 0x12ca2
xorl %eax, %eax
movslq (%rdi,%rax,4), %rcx
movl (%rsp,%rcx,4), %ecx
incl %ecx
movl %ecx, (%rdi,%rax,4)
incq %rax
cmpq %rax, %rdx
jne 0x12c8e
incl %r15d
movq (%r14), %rsi
decl %edx
movl %r15d, %ecx
movl $0x1, %r8d
callq 0x3e184
movq 0x41329(%rip), %r14     # 0x53fe8
leaq 0x31687(%rip), %rsi     # 0x4434d
movl $0x1d, %edx
movq %r14, %rdi
callq 0x7340
movq 0x38(%rbx), %rsi
movq %r14, %rdi
callq 0x72a0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x72b0
movsbl %al, %esi
movq %r15, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x71d0
leaq 0xa0(%rbx), %r15
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movq %r15, %rdi
movq %rax, %rsi
callq 0x15a90
leaq 0x3163c(%rip), %rsi     # 0x4436b
movl $0x20, %edx
movq %r14, %rdi
callq 0x7340
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movq %r14, %rdi
movq %rax, %rsi
callq 0x72a0
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x72b0
movsbl %al, %esi
movq %r14, %rdi
callq 0x7040
movq %rax, %rdi
callq 0x71d0
movq %rbx, %rdi
callq 0x103b0
movq %r15, %rdi
callq 0xfaf6
cmpb $0x0, 0xf1(%rbx)
jne 0x12dc9
movq 0x88(%rbx), %rdi
movq 0x98(%rbx), %rsi
pxor %xmm0, %xmm0
movdqu %xmm0, 0x88(%rbx)
movq $0x0, 0x98(%rbx)
testq %rdi, %rdi
je 0x12dc9
subq %rdi, %rsi
callq 0x72f0
cmpb $0x1, 0xf0(%rbx)
jne 0x12df6
leaq 0xd0(%rbx), %rdi
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
movq %rax, %rsi
callq 0x15af0
movq %rbx, %rdi
callq 0x1049c
cmpb $0x1, 0xf8(%rbx)
jne 0x12e22
leaq 0x100(%rbx), %rdi
movq %rsp, %rdx
movq $0x0, (%rdx)
movl $0x100000, %esi         # imm = 0x100000
callq 0x15b54
movq %rbx, %rdi
callq 0x1083c
movq 0x38(%rbx), %rax
cqto
idivq 0xe8(%rbx)
decq %rax
movq %rax, 0x48(%rbx)
addq $0x408, %rsp            # imm = 0x408
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq