// File: /workspace/github_c_makefile_star2_O0/felipelouza[P]egap/util.c
// Function: mergeBWTandLCP
void mergeBWTandLCP(g_data *g, bool lastRound)
{
  if(sizeof(symbol)>sizeof(palette)) die("Sorry, alphabet is too large (mergeBWTandLCP");
  assert(!g->lcpMerge || g->blockBeginsAt!=NULL); // if lcpMerge we need g->blockBeginsAt
  FILE *daOutFile=NULL;

  check_g_data(g);
  array_clear(g->inCnt,g->numBwt,0);
  if(g->outputDA && lastRound)
    daOutFile = openDAFile(g);
  if(g->extMem) {
    open_bw_files(g);// open files in read mode
    rewind_bw_files(g);   // set file pointers at the beginning of each BWT
    // mmap merge values
    int fd = open(g->merge_fname,O_RDWR);
    if(fd == -1) die(__func__);
    g->mergeColor = mmap(NULL,g->mergeLen*sizeof(palette),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(g->mergeColor == MAP_FAILED) die(__func__);
    #ifdef USE_MMAP_ADVISE
    madvise(g->mergeColor, g->mergeLen*sizeof(palette), MADV_SEQUENTIAL);
    #endif
    if(close(fd)!=0) die(__func__);
  }
  symbol *bwtout = (symbol *) g->mergeColor;   // merged BWT stored in mergeColor
  for (customInt i = 0; i < g->mergeLen; ++i) {
    int currentColor = g->mergeColor[i];
    assert(currentColor < g->numBwt);
    // check that all LCP values have been obtained
    if(g->lcpCompute && lastRound)
      assert( tba_get(g->bitB,i)==3 ); 
    // if requested output merge array
    if(g->outputDA && lastRound) 
      if(fputc(currentColor, daOutFile)==EOF)
        die("mergeBWTandLCP: Error writing to Document Array file");   
    // save new BWT char overwriting mergeColor[i]
    if(g->extMem) {
      int e = fread(bwtout+i,sizeof(symbol),1,g->bwf[currentColor]);
      if(e!=1) die(__func__);
    }      
    else bwtout[i] = g->bws[currentColor][g->inCnt[currentColor]];
    if(lastRound) bwtout[i] = alpha_enlarge(bwtout[i]); 
    
    if(g->lcpMerge) { // compute lcp value and store it to blockBeginsAt[]
      lcpInt tmp = g->lcps[currentColor][g->inCnt[currentColor]]; // lcp retrieved from file (suffixes from the same string)      
      if(g->blockBeginsAt[i]>0)
        g->blockBeginsAt[i] -= 1;  // lcp computed by the merging algorithm 
      else 
        g->blockBeginsAt[i] = tmp; // lcp retrieved from file (suffixes from the same string) 
    }
    g->inCnt[currentColor]++; // one more char read from currentColor BWT/LCP
  }  
  // final check on the merging 
  for(int i=0;i<g->numBwt;i++) assert(g->inCnt[i]==g->bwtLen[i]);
  if(g->extMem) close_bw_files(g);

  // merging done: copy back to g->bws[0] or to file
  if(g->extMem) {
    // printf("Copy back to file. Bytes: %ld, offset %ld\n",g->mergeLen, g->symb_offset);
    int fd = open(g->bwfname,O_WRONLY);
    if(fd == -1) die(__func__);
    huge_pwrite(fd, bwtout,sizeof(symbol)*g->mergeLen,sizeof(symbol)*g->symb_offset);
    if(close(fd)!=0) die(__func__);
    // unmap mergeColor
    fd = munmap(g->mergeColor,g->mergeLen*sizeof(palette));
    if(fd == -1) die(__func__);
    g->mergeColor=NULL;  
  }
  else 
    memcpy(g->bws[0],bwtout,g->mergeLen*sizeof(symbol));
  // close document array file 
  if(g->outputDA && lastRound)
      if(fclose(daOutFile)!=0) die("mergeBWTandLCP: Error closing Document Array file");   
  //copy merged values back to g->lcps[0]
  if(g->lcpMerge)
      memcpy(g->lcps[0],g->blockBeginsAt,g->mergeLen*sizeof(lcpInt)); // copy lcp values back to g->lcps[0]
}

// Assembly:
subq $0x48, %rsp
movb %sil, %al
movq %rdi, 0x40(%rsp)
andb $0x1, %al
movb %al, 0x3f(%rsp)
movq $0x0, 0x30(%rsp)
movq 0x40(%rsp), %rdi
callq 0x3dd0
movq 0x40(%rsp), %rax
movq 0x5118(%rax), %rdi
movq 0x40(%rsp), %rax
movslq 0x20(%rax), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x3310
movq 0x40(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x43f4
testb $0x1, 0x3f(%rsp)
je 0x43f4
movq 0x40(%rsp), %rdi
callq 0x4870
movq %rax, 0x30(%rsp)
movq 0x40(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x44de
movq 0x40(%rsp), %rdi
callq 0x6da0
movq 0x40(%rsp), %rdi
callq 0x6e70
movq 0x40(%rsp), %rax
movq 0x50d8(%rax), %rdi
movl $0x2, %esi
movb $0x0, %al
callq 0x22e0
movl %eax, 0x2c(%rsp)
cmpl $-0x1, 0x2c(%rsp)
jne 0x4446
leaq 0x10873(%rip), %rdi     # 0x14cb4
callq 0x3ce0
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rsi
shlq $0x0, %rsi
movl 0x2c(%rsp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x3, %edx
movl $0x1, %ecx
movq %r9, %rdi
callq 0x2220
movq %rax, %rcx
movq 0x40(%rsp), %rax
movq %rcx, 0x50e8(%rax)
movq 0x40(%rsp), %rax
movq $-0x1, %rcx
cmpq %rcx, 0x50e8(%rax)
jne 0x449f
leaq 0x1081a(%rip), %rdi     # 0x14cb4
callq 0x3ce0
movq 0x40(%rsp), %rax
movq 0x50e8(%rax), %rdi
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rsi
shlq $0x0, %rsi
movl $0x2, %edx
callq 0x22d0
movl 0x2c(%rsp), %edi
callq 0x2150
cmpl $0x0, %eax
je 0x44dc
leaq 0x107dd(%rip), %rdi     # 0x14cb4
callq 0x3ce0
jmp 0x44de
movq 0x40(%rsp), %rax
movq 0x50e8(%rax), %rax
movq %rax, 0x20(%rsp)
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq 0x40(%rsp), %rcx
cmpq 0x28(%rcx), %rax
jae 0x46dc
movq 0x40(%rsp), %rax
movq 0x50e8(%rax), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, 0x14(%rsp)
movq 0x40(%rsp), %rax
testb $0x1, 0x3e(%rax)
je 0x4539
testb $0x1, 0x3f(%rsp)
je 0x4539
jmp 0x4539
movq 0x40(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x456c
testb $0x1, 0x3f(%rsp)
je 0x456c
movl 0x14(%rsp), %edi
movq 0x30(%rsp), %rsi
callq 0x2170
cmpl $-0x1, %eax
jne 0x456a
leaq 0x1075e(%rip), %rdi     # 0x14cc3
callq 0x3ce0
jmp 0x456c
movq 0x40(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x45bc
movq 0x20(%rsp), %rdi
addq 0x18(%rsp), %rdi
movq 0x40(%rsp), %rax
movq 0x50a0(%rax), %rax
movslq 0x14(%rsp), %rcx
movq (%rax,%rcx,8), %rcx
movl $0x1, %edx
movq %rdx, %rsi
callq 0x2090
movl %eax, 0x10(%rsp)
cmpl $0x1, 0x10(%rsp)
je 0x45ba
leaq 0x106ff(%rip), %rdi     # 0x14cb4
callq 0x3ce0
jmp 0x45f2
movq 0x40(%rsp), %rax
movq (%rax), %rax
movslq 0x14(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rsp), %rcx
movq 0x5118(%rcx), %rcx
movslq 0x14(%rsp), %rdx
movq (%rcx,%rdx,8), %rcx
movb (%rax,%rcx), %dl
movq 0x20(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
testb $0x1, 0x3f(%rsp)
je 0x461b
movq 0x20(%rsp), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %edi
callq 0x124e0
movb %al, %dl
movq 0x20(%rsp), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x40(%rsp), %rax
testb $0x1, 0x3d(%rax)
je 0x46ac
movq 0x40(%rsp), %rax
movq 0x88(%rax), %rax
movslq 0x14(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rsp), %rcx
movq 0x5118(%rcx), %rcx
movslq 0x14(%rsp), %rdx
movq (%rcx,%rdx,8), %rcx
movb (%rax,%rcx), %al
movb %al, 0xf(%rsp)
movq 0x40(%rsp), %rax
movq 0x98(%rax), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jle 0x4692
movq 0x40(%rsp), %rax
movq 0x98(%rax), %rax
movq 0x18(%rsp), %rcx
movzbl (%rax,%rcx), %edx
subl $0x1, %edx
movb %dl, (%rax,%rcx)
jmp 0x46aa
movb 0xf(%rsp), %dl
movq 0x40(%rsp), %rax
movq 0x98(%rax), %rax
movq 0x18(%rsp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x46ac
movq 0x40(%rsp), %rax
movq 0x5118(%rax), %rax
movslq 0x14(%rsp), %rcx
movq (%rax,%rcx,8), %rdx
addq $0x1, %rdx
movq %rdx, (%rax,%rcx,8)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0x44f8
movl $0x0, 0x8(%rsp)
movl 0x8(%rsp), %eax
movq 0x40(%rsp), %rcx
cmpl 0x20(%rcx), %eax
jge 0x4701
jmp 0x46f4
movl 0x8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x8(%rsp)
jmp 0x46e4
movq 0x40(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x4716
movq 0x40(%rsp), %rdi
callq 0x6f10
movq 0x40(%rsp), %rax
testb $0x1, 0x69(%rax)
je 0x47dd
movq 0x40(%rsp), %rdi
addq $0xa0, %rdi
movl $0x1, %esi
movb $0x0, %al
callq 0x22e0
movl %eax, 0x4(%rsp)
cmpl $-0x1, 0x4(%rsp)
jne 0x4754
leaq 0x10565(%rip), %rdi     # 0x14cb4
callq 0x3ce0
movl 0x4(%rsp), %edi
movq 0x20(%rsp), %rsi
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rdx
shlq $0x0, %rdx
movq 0x40(%rsp), %rax
movq 0x30(%rax), %rcx
shlq $0x0, %rcx
callq 0x7820
movl 0x4(%rsp), %edi
callq 0x2150
cmpl $0x0, %eax
je 0x4796
leaq 0x10523(%rip), %rdi     # 0x14cb4
callq 0x3ce0
movq 0x40(%rsp), %rax
movq 0x50e8(%rax), %rdi
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rsi
shlq $0x0, %rsi
callq 0x2280
movl %eax, 0x4(%rsp)
cmpl $-0x1, 0x4(%rsp)
jne 0x47cb
leaq 0x104ee(%rip), %rdi     # 0x14cb4
callq 0x3ce0
movq 0x40(%rsp), %rax
movq $0x0, 0x50e8(%rax)
jmp 0x47ff
movq 0x40(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rdi
movq 0x20(%rsp), %rsi
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rdx
shlq $0x0, %rdx
callq 0x21e0
movq 0x40(%rsp), %rax
cmpl $0x0, 0x44(%rax)
je 0x482e
testb $0x1, 0x3f(%rsp)
je 0x482e
movq 0x30(%rsp), %rdi
callq 0x20d0
cmpl $0x0, %eax
je 0x482c
leaq 0x104d1(%rip), %rdi     # 0x14cf8
callq 0x3ce0
jmp 0x482e
movq 0x40(%rsp), %rax
testb $0x1, 0x3d(%rax)
je 0x4866
movq 0x40(%rsp), %rax
movq 0x88(%rax), %rax
movq (%rax), %rdi
movq 0x40(%rsp), %rax
movq 0x98(%rax), %rsi
movq 0x40(%rsp), %rax
movq 0x28(%rax), %rdx
shlq $0x0, %rdx
callq 0x21e0
addq $0x48, %rsp
retq
nopl (%rax,%rax)