// File: /workspace/github_c_makefile_star2_O2/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, %rcx
leaq 0xa933(%rip), %rdx      # 0xd91e
leaq 0xb138(%rip), %r8       # 0xe12a
leaq 0x2010(%rsp), %r14
movl $0x1000, %esi           # imm = 0x1000
movq %r14, %rdi
movq %rcx, (%rsp)
xorl %eax, %eax
callq 0x2140
leaq 0xc1d1(%rip), %rsi      # 0xf1e5
movq %r14, %rdi
callq 0x21e0
testq %rax, %rax
je 0x354c
movq %rax, %r15
pushq $0x2
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x2260
testl %eax, %eax
jne 0x3558
movq %r15, %rdi
callq 0x2190
movq %rax, %r14
movq %r15, %rdi
callq 0x2120
testq %r14, %r14
js 0x3561
movq %r15, 0x8(%rsp)
testb $0x7, %r14b
jne 0x356f
movq %r14, %r15
shrq $0x3, %r15
movl %r15d, 0x20(%rbx)
cmpl $0x1, %r15d
jne 0x3089
cmpb $0x0, 0x3e(%rbx)
jne 0x3089
cmpl $0x0, 0x40(%rbx)
je 0x333f
cmpl $0x0, 0x44(%rbx)
je 0x317f
shlq $0x1d, %r14
sarq $0x1d, %r14
movq %r14, %rdi
callq 0xbce0
movq %rax, 0x10(%rbx)
leaq 0xa870(%rip), %rdx      # 0xd91e
leaq 0xab04(%rip), %r8       # 0xdbb9
leaq 0x2010(%rsp), %r15
movl $0x1000, %esi           # imm = 0x1000
movq %r15, %rdi
movq (%rsp), %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xc10e(%rip), %rsi      # 0xf1e5
movq %r15, %rdi
callq 0x21e0
testq %rax, %rax
je 0x354c
movq %rax, %r12
xorl %r14d, %r14d
pushq $0x8
popq %r13
pushq $0x1
popq %rbp
xorl %r15d, %r15d
movslq 0x20(%rbx), %rax
cmpq %rax, %r14
jge 0x3130
leaq 0x10(%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
movq %r12, %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x354c
movq 0x10(%rbx), %rax
movq %r15, (%rax,%r14,8)
addq 0x10(%rsp), %r15
incq %r14
jmp 0x30f8
leaq 0x10(%rsp), %r13
movq %r15, (%r13)
movq %r12, %rdi
callq 0x20e0
leaq 0xa7e6(%rip), %rsi      # 0xd92e
leaq 0x2010(%rsp), %rdi
callq 0x21e0
movq %rax, %r15
pushq $0x8
popq %rsi
pushq $0x1
popq %rdx
movq %r13, %rdi
movq %rax, %rcx
callq 0x2390
cmpq $0x1, %rax
jne 0x354c
movq %r15, %rdi
callq 0x20e0
movl 0x20(%rbx), %r15d
movslq %r15d, %r14
shlq $0x3, %r14
movq %r14, %rdi
callq 0xbce0
movq %rax, %r12
movq %rax, 0x8(%rbx)
movq %r14, %rdi
callq 0xbce0
movq %rax, (%rbx)
testq %r12, %r12
je 0x354c
testq %rax, %rax
je 0x354c
xorl %r13d, %r13d
pushq $0x8
popq %rbp
pushq $0x1
popq %r14
xorl %r12d, %r12d
movslq %r15d, %rax
cmpq %rax, %r13
jge 0x3209
leaq 0x10(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rdx
movq 0x8(%rsp), %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x354c
movq 0x10(%rsp), %rax
cmpq $-0x1, %rax
je 0x352e
movq 0x8(%rbx), %rcx
movq %rax, (%rcx,%r13,8)
addq %rax, %r12
incq %r13
movl 0x20(%rbx), %r15d
jmp 0x31bf
movq %r12, 0x28(%rbx)
movq 0x8(%rsp), %rdi
callq 0x20e0
leaq 0xa0(%rbx), %r14
leaq 0xa6f9(%rip), %rdx      # 0xd91e
leaq 0xa6fe(%rip), %r8       # 0xd92a
movl $0x1000, %esi           # imm = 0x1000
movq %r14, %rdi
movq (%rsp), %rcx
xorl %eax, %eax
callq 0x2140
pushq $0x2
popq %rsi
movq %r14, %rdi
xorl %eax, %eax
callq 0x22f0
cmpl $-0x1, %eax
je 0x354c
movl %eax, %ebp
cmpb $0x0, 0x72(%rbx)
jne 0x3263
cmpb $0x1, 0x69(%rbx)
jne 0x329d
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
xorl %edi, %edi
movq %r12, %rsi
movl %ebp, %r8d
xorl %r9d, %r9d
callq 0x2230
movq (%rbx), %rcx
movq %rax, (%rcx)
movq (%rbx), %rax
movq (%rax), %rdi
cmpq $-0x1, %rdi
je 0x354c
movq 0x28(%rbx), %rsi
pushq $0x2
popq %rdx
callq 0x22e0
jmp 0x32c6
movq %r12, %rdi
callq 0xbce0
testq %rax, %rax
je 0x354c
movq %rax, %r14
movl %ebp, %edi
movq %rax, %rsi
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x59c0
movq (%rbx), %rax
movq %r14, (%rax)
movl %ebp, %edi
callq 0x2160
testl %eax, %eax
jne 0x354c
movl 0x20(%rbx), %ecx
cmpl $0x2, %ecx
pushq $0x1
popq %rax
cmovgel %ecx, %eax
decl %eax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x3303
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
jmp 0x32e5
movq %rbx, %rdi
callq 0xbb78
movb $0x1, %bpl
cmpb $0x0, 0x69(%rbx)
je 0x332b
movq (%rbx), %rax
movq 0x28(%rbx), %rsi
movq (%rax), %rdi
callq 0x2290
testl %eax, %eax
jne 0x357b
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 0x33af
leaq 0xa7ea(%rip), %r15      # 0xdb39
leaq 0xa7ec(%rip), %r9       # 0xdb42
leaq 0x10(%rsp), %r12
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
movq %r15, %rdx
movq (%rsp), %r14
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x4c(%rbx), %r8d
leaq 0x9fbb(%rip), %r9       # 0xd33a
leaq 0x1010(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r12, %rdi
movq %r13, %rsi
callq 0x2330
testl %eax, %eax
jne 0x3587
movl 0x44(%rbx), %r8d
testl %r8d, %r8d
je 0x341f
leaq 0xa77a(%rip), %r15      # 0xdb39
leaq 0xa798(%rip), %r9       # 0xdb5e
leaq 0x10(%rsp), %r12
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
movq %r15, %rdx
movq (%rsp), %r14
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x44(%rbx), %r8d
leaq 0x9f0e(%rip), %r9       # 0xd2fd
leaq 0x1010(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r12, %rdi
movq %r13, %rsi
callq 0x2330
testl %eax, %eax
jne 0x3593
cmpl $0x0, 0x54(%rbx)
je 0x3488
leaq 0xa4f2(%rip), %r15      # 0xd91e
leaq 0xa747(%rip), %r8       # 0xdb7a
leaq 0x10(%rsp), %r12
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
movq %r15, %rdx
movq (%rsp), %r14
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0x9f2c(%rip), %r8       # 0xd384
leaq 0x1010(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r12, %rdi
movq %r13, %rsi
callq 0x2330
testl %eax, %eax
jne 0x359f
movl 0x50(%rbx), %r8d
testl %r8d, %r8d
je 0x34f8
leaq 0xa6a1(%rip), %r15      # 0xdb39
leaq 0xa6fb(%rip), %r9       # 0xdb9a
leaq 0x10(%rsp), %r12
movl $0x1000, %esi           # imm = 0x1000
movq %r12, %rdi
movq %r15, %rdx
movq (%rsp), %r14
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x50(%rbx), %r8d
leaq 0xa6d8(%rip), %r9       # 0xdba0
leaq 0x1010(%rsp), %r13
movl $0x1000, %esi           # imm = 0x1000
movq %r13, %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r12, %rdi
movq %r13, %rsi
callq 0x2330
testl %eax, %eax
jne 0x35ab
leaq 0x10(%rsp), %rdi
pushq $0x8
popq %rsi
pushq $0x1
popq %rdx
movq 0x8(%rsp), %r14
movq %r14, %rcx
callq 0x20a0
cmpq $0x1, %rax
jne 0x354c
movq 0x10(%rsp), %rax
movq %rax, 0x28(%rbx)
movq %r14, %rdi
callq 0x20e0
xorl %ebp, %ebp
jmp 0x332b
movq 0xfac3(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0xa67f(%rip), %rsi      # 0xdbbe
pushq $-0x1
popq %rdx
pushq $-0x2
popq %rcx
xorl %eax, %eax
callq 0x21c0
leaq 0xa5a2(%rip), %rdi      # 0xdaf5
callq 0x35b7
leaq 0xa5a4(%rip), %rdi      # 0xdb03
jmp 0x3568
leaq 0xa5a7(%rip), %rdi      # 0xdb0f
callq 0x2320
jmp 0x354c
leaq 0xa5a6(%rip), %rdi      # 0xdb1c
callq 0x35b7
leaq 0xa2ab(%rip), %rdi      # 0xd82d
callq 0x35b7
leaq 0xa5ba(%rip), %rdi      # 0xdb48
callq 0x35b7
leaq 0xa5ca(%rip), %rdi      # 0xdb64
callq 0x35b7
leaq 0xa5de(%rip), %rdi      # 0xdb84
callq 0x35b7
leaq 0xa5f1(%rip), %rdi      # 0xdba3
callq 0x35b7