// File: /workspace/github_c_makefile_star2_O3/felipelouza[P]egap/util.c
// Function: readBWTsingle
bool readBWTsingle(char *path, g_data *g)
{
  char filename[Filename_size];
  customInt n=0;
  
  // open .size file and get number of (multi) BWT
  snprintf(filename,Filename_size,"%s.%s",path,LEN_EXT);
  FILE *f = fopen(filename,"r");
  if(f==NULL) die(__func__);
  if(fseek(f, 0, SEEK_END) != 0) {
    perror("fseek error");
    die(__func__);
  }
  off_t flen = ftello(f);
  rewind(f);
  if(flen < 0) {
    perror("ftello error");
    die(__func__);
  }
  else if(flen%8!=0) 
    die("Invalid format of ."LEN_EXT" file");
  g->numBwt = flen/8;
  assert(g->numBwt>0);

  // single BWT with no lcp or dbInfo computation: nothing to do
  if(g->numBwt==1 && !g->lcpCompute && g->dbOrder==0){ 
    if(g->outputSA) { // if there is a single (multi)-bwt the DA does not change
      char tmp1[Filename_size];
      char tmp2[Filename_size];
      snprintf(tmp1,Filename_size,"%s.%d.%s",path,g->outputSA, SA_BL_EXT);
      snprintf(tmp2,Filename_size,"%s.%d.%s",path,g->outputSA, SA_EXT);
      if(rename(tmp1,tmp2)!=0)
        die("Cannot rename SA file");
    }
    if(g->outputDA) { // if there is a single (multi)-bwt the DA does not change
      char tmp1[Filename_size];
      char tmp2[Filename_size];
      snprintf(tmp1,Filename_size,"%s.%d.%s",path,g->outputDA, DA_BL_EXT);
      snprintf(tmp2,Filename_size,"%s.%d.%s",path,g->outputDA, DA_EXT);
      if(rename(tmp1,tmp2)!=0)
        die("Cannot rename DA file");
    }
    if(g->outputQS) { // if there is a single (multi)-bwt the QS does not change
      char tmp1[Filename_size];
      char tmp2[Filename_size];
      snprintf(tmp1,Filename_size,"%s.%s",path,QS_BL_EXT);
      snprintf(tmp2,Filename_size,"%s.%s",path,QS_EXT);
      if(rename(tmp1,tmp2)!=0)
        die("Cannot rename QS file");
    }
    if(g->outputSL) { // if there is a single (multi)-bwt the SL does not change
      char tmp1[Filename_size];
      char tmp2[Filename_size];
      snprintf(tmp1,Filename_size,"%s.%d.%s",path,g->outputSL, SL_BL_EXT);
      snprintf(tmp2,Filename_size,"%s.%d.%s",path,g->outputSL, SL_EXT);
      if(rename(tmp1,tmp2)!=0)
        die("Cannot rename SL file");
    }
    size_t size;
    size_t r = fread(&size, 8, 1, f);// sizes are stored in 64 bits 
    if(r!=1) die(__func__);
    g->mergeLen = size;
    fclose(f);
    return false;
  }

  if(g->outputDA) { 
    g->bwtDocs = (customInt *) malloc (g->numBwt * sizeof(customInt));
    snprintf(filename,Filename_size,"%s.%s",path,DOCS_EXT);
    FILE *f = fopen(filename,"r");
    if(f==NULL) die(__func__);
    size_t sum=0;
    for (int i = 0; i < g->numBwt; ++i) {
      customInt docs;
      size_t r = fread(&docs, 8, 1, f);// docs are stored in 64 bits 
      if(r!=1) die(__func__);
      g->bwtDocs[i] = sum;
      sum+=docs;
      //printf("--> %zu\n",  docs);
    }
    fclose(f);
    f = fopen(filename,"wb");
    size_t e = fwrite(&sum,8,1,f);
    if(e!=1) die(__func__);
    fclose(f);
  }

  // we have the number of (multi)BWTs: allocate g->bwtLen and g->bws  
  g->bwtLen = (customInt *) malloc (g->numBwt * sizeof(customInt));
  g->bws = (symbol **) malloc (g->numBwt * sizeof(symbol *));
  if(!g->bwtLen || !g->bws) die(__func__);
  // read and store sizes of multibwt in g->bwtLen 
  for (int i = 0; i < g->numBwt; ++i) {
    size_t size;
    size_t r = fread(&size, 8, 1, f);// sizes are stored in 64 bits 
    if(r!=1) die(__func__);
    if(size>MAX_OUTPUT_SIZE) {
      fprintf(stderr,"Bwt len %zu larger than maximum sequence size: %llu\n",
      size,MAX_OUTPUT_SIZE);
      die(__func__);
    }
    g->bwtLen[i] = size;
    n += size;
  }
  g->mergeLen = n;
  fclose(f);
  
  // We now have g->mergeLen: open and read concatenated bwt file 
  snprintf(g->bwfname,Filename_size,"%s.%s",path,BWT_EXT);
  int fd = open(g->bwfname,O_RDWR);
  if(fd == -1) die(__func__);
  // allocate/mmap memory for BWT concatenation and read whole file
  if(g->mmapBWT || g->extMem) { // mmap input file to RAM modifications are written back to the input file 
    g->bws[0] = mmap(NULL,n*sizeof(symbol),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(g->bws[0] == MAP_FAILED) die(__func__);
    #ifdef USE_MMAP_ADVISE
    // the first access is sequential to remap alphabet
    madvise(g->bws[0], g->mergeLen*sizeof(symbol), MADV_SEQUENTIAL);
    #endif
  }
  else { // allocate memory and read from file descriptor
    uint8_t *b = malloc(n*sizeof(symbol));
    if(!b) die(__func__);  
    huge_pread(fd,b,sizeof(symbol)*n,0);
    g->bws[0] = (symbol *) b;
  } 
  if(close(fd)!=0) die(__func__);

  // init g->bws[1..]: we do this even for g->extMem, since g->bws[i]-g->bws[0] is the starting point in the file of the i-th bwt
  for (int i = 0; i < g->numBwt -1; ++i)  
    g->bws[i+1] = g->bws[i] + g->bwtLen[i]; 
    
  // remap BWTs and also init g->sizeOfAlpha etc   
  remap_bwts(g);    
  if(g->extMem) { // if we are working in external memory don't keep the BWTs mmaped 
    int e = munmap(g->bws[0],g->mergeLen*sizeof(symbol));
    if(e) die("main (unmap bws)");
  }
  return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3018, %rsp           # imm = 0x3018
movq %rsi, %rbx
movq %rdi, %r14
leaq 0xb4c4(%rip), %rdx      # 0xe91e
leaq 0xbd04(%rip), %r8       # 0xf165
leaq 0x2010(%rsp), %r15
movl $0x1000, %esi           # imm = 0x1000
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xcdab(%rip), %rsi      # 0x1022d
movq %r15, %rdi
callq 0x21e0
testq %rax, %rax
je 0x3999
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x2260
testl %eax, %eax
jne 0x39aa
movq %r15, %rdi
callq 0x2190
movq %rax, %r12
movq %r15, %rdi
callq 0x2120
testq %r12, %r12
js 0x39af
testb $0x7, %r12b
jne 0x39b4
movq %r12, %rbp
shrq $0x3, %rbp
movl %ebp, 0x20(%rbx)
cmpl $0x1, %ebp
jne 0x34f2
cmpb $0x0, 0x3e(%rbx)
jne 0x34f2
cmpl $0x0, 0x40(%rbx)
je 0x37bb
cmpl $0x0, 0x44(%rbx)
je 0x35fb
shlq $0x1d, %r12
sarq $0x1d, %r12
movq %r12, %rdi
callq 0xc70e
movq %rax, 0x10(%rbx)
leaq 0xb407(%rip), %rdx      # 0xe91e
leaq 0xb6d6(%rip), %r8       # 0xebf4
leaq 0x2010(%rsp), %r12
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xccee(%rip), %rsi      # 0x1022d
movq %r12, %rdi
callq 0x21e0
testq %rax, %rax
je 0x3999
movq %rax, %r12
movq %r14, 0x8(%rsp)
cmpl $0x0, 0x20(%rbx)
jle 0x35a2
xorl %r14d, %r14d
leaq 0x10(%rsp), %r13
xorl %ebp, %ebp
movl $0x8, %esi
movl $0x1, %edx
movq %r13, %rdi
movq %r12, %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x3999
movq 0x10(%rbx), %rax
movq %rbp, (%rax,%r14,8)
addq 0x10(%rsp), %rbp
incq %r14
movslq 0x20(%rbx), %rax
cmpq %rax, %r14
jl 0x3568
jmp 0x35a4
xorl %ebp, %ebp
leaq 0x10(%rsp), %r13
movq %rbp, (%r13)
movq %r12, %rdi
callq 0x20e0
leaq 0xb372(%rip), %rsi      # 0xe92e
leaq 0x2010(%rsp), %rdi
callq 0x21e0
movq %rax, %r12
movl $0x8, %esi
movl $0x1, %edx
movq %r13, %rdi
movq %rax, %rcx
callq 0x2390
cmpq $0x1, %rax
movq 0x8(%rsp), %r14
jne 0x3999
movq %r12, %rdi
callq 0x20e0
movl 0x20(%rbx), %ebp
movslq %ebp, %r12
shlq $0x3, %r12
movq %r12, %rdi
callq 0xc70e
movq %rax, %r13
movq %rax, 0x8(%rbx)
movq %r12, %rdi
callq 0xc70e
movq %rax, (%rbx)
testq %r13, %r13
je 0x3999
testq %rax, %rax
je 0x3999
testl %ebp, %ebp
jle 0x3683
xorl %ebp, %ebp
leaq 0x10(%rsp), %r13
xorl %r12d, %r12d
movl $0x8, %esi
movl $0x1, %edx
movq %r13, %rdi
movq %r15, %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x3999
movq 0x10(%rsp), %rax
cmpq $-0x1, %rax
je 0x39a5
movq 0x8(%rbx), %rcx
movq %rax, (%rcx,%rbp,8)
addq %rax, %r12
incq %rbp
movslq 0x20(%rbx), %rax
cmpq %rax, %rbp
jl 0x363c
jmp 0x3686
xorl %r12d, %r12d
movq %r12, 0x28(%rbx)
movq %r15, %rdi
callq 0x20e0
leaq 0xa0(%rbx), %r15
leaq 0xb27e(%rip), %rdx      # 0xe91e
leaq 0xb283(%rip), %r8       # 0xe92a
movl $0x1000, %esi           # imm = 0x1000
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r15, %rdi
movl $0x2, %esi
xorl %eax, %eax
callq 0x22f0
cmpl $-0x1, %eax
je 0x3999
movl %eax, %ebp
cmpb $0x0, 0x72(%rbx)
jne 0x36df
cmpb $0x1, 0x69(%rbx)
jne 0x371f
xorl %edi, %edi
movq %r12, %rsi
movl $0x3, %edx
movl $0x1, %ecx
movl %ebp, %r8d
xorl %r9d, %r9d
callq 0x2230
movq (%rbx), %rcx
movq %rax, (%rcx)
movq (%rbx), %rax
movq (%rax), %rdi
cmpq $-0x1, %rdi
je 0x3999
movq 0x28(%rbx), %rsi
movl $0x2, %edx
callq 0x22e0
jmp 0x3748
movq %r12, %rdi
callq 0xc70e
testq %rax, %rax
je 0x3999
movq %rax, %r14
movl %ebp, %edi
movq %rax, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x5f2d
movq (%rbx), %rax
movq %r14, (%rax)
movl %ebp, %edi
callq 0x2160
testl %eax, %eax
jne 0x3999
movl 0x20(%rbx), %eax
cmpl $0x2, %eax
jl 0x377f
decl %eax
xorl %ecx, %ecx
movq (%rbx), %rdx
movq 0x8(%rbx), %rsi
movq (%rdx,%rcx,8), %rdi
addq (%rsi,%rcx,8), %rdi
movq %rdi, 0x8(%rdx,%rcx,8)
incq %rcx
cmpq %rcx, %rax
jne 0x3763
movq %rbx, %rdi
callq 0xc5bd
movb $0x1, %bpl
cmpb $0x0, 0x69(%rbx)
je 0x37a7
movq (%rbx), %rax
movq 0x28(%rbx), %rsi
movq (%rax), %rdi
callq 0x2290
testl %eax, %eax
jne 0x39c0
movl %ebp, %eax
addq $0x3018, %rsp           # imm = 0x3018
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x4c(%rbx), %r8d
testl %r8d, %r8d
je 0x3827
leaq 0xb3a9(%rip), %r12      # 0xeb74
leaq 0xb3ab(%rip), %r9       # 0xeb7d
leaq 0x10(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x4c(%rbx), %r8d
leaq 0xab43(%rip), %r9       # 0xe33a
leaq 0x1010(%rsp), %rbp
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2330
testl %eax, %eax
jne 0x39cc
movl 0x44(%rbx), %r8d
testl %r8d, %r8d
je 0x3893
leaq 0xb33d(%rip), %r12      # 0xeb74
leaq 0xb35b(%rip), %r9       # 0xeb99
leaq 0x10(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x44(%rbx), %r8d
leaq 0xaa9a(%rip), %r9       # 0xe2fd
leaq 0x1010(%rsp), %rbp
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2330
testl %eax, %eax
jne 0x39d8
cmpl $0x0, 0x54(%rbx)
je 0x38f8
leaq 0xb07e(%rip), %r12      # 0xe91e
leaq 0xb30e(%rip), %r8       # 0xebb5
leaq 0x10(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xaabc(%rip), %r8       # 0xe384
leaq 0x1010(%rsp), %rbp
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2330
testl %eax, %eax
jne 0x39e4
movl 0x50(%rbx), %r8d
testl %r8d, %r8d
je 0x3964
leaq 0xb26c(%rip), %r12      # 0xeb74
leaq 0xb2c6(%rip), %r9       # 0xebd5
leaq 0x10(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x50(%rbx), %r8d
leaq 0xb2a7(%rip), %r9       # 0xebdb
leaq 0x1010(%rsp), %rbp
movl $0x1000, %esi           # imm = 0x1000
movq %rbp, %rdi
movq %r12, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r13, %rdi
movq %rbp, %rsi
callq 0x2330
testl %eax, %eax
jne 0x39f0
leaq 0x10(%rsp), %rdi
movl $0x8, %esi
movl $0x1, %edx
movq %r15, %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x3999
movq 0x10(%rsp), %rax
movq %rax, 0x28(%rbx)
movq %r15, %rdi
callq 0x20e0
xorl %ebp, %ebp
jmp 0x37a7
leaq 0xb190(%rip), %rdi      # 0xeb30
callq 0x39fc
callq 0x2429
callq 0x2410
callq 0x2454
leaq 0xb19c(%rip), %rdi      # 0xeb57
callq 0x39fc
leaq 0xae66(%rip), %rdi      # 0xe82d
callq 0x39fc
leaq 0xb1b0(%rip), %rdi      # 0xeb83
callq 0x39fc
leaq 0xb1c0(%rip), %rdi      # 0xeb9f
callq 0x39fc
leaq 0xb1d4(%rip), %rdi      # 0xebbf
callq 0x39fc
leaq 0xb1e7(%rip), %rdi      # 0xebde
callq 0x39fc