// File: adamnovak[P]rlcsa/merge_rlcsa.cpp
// Function: main
int
main(int argc, char** argv)
{
  std::cout << "RLCSA merger" << std::endl;
  if(argc < 3)
  {
    std::cout << "Usage: merge_rlcsa [-threads] original additional [additional2...]" << std::endl;
    return 1;
  }

  int original_parameter = 2, additional_parameter = 3, threads_parameter = 1;

  usint threads = 1;
  if(argc > threads_parameter && argv[threads_parameter][0] == '-')
  {
    threads = std::min(MAX_THREADS, std::max(atoi(argv[threads_parameter] + 1), 1));
  }
  else 
  {
    original_parameter--;
    additional_parameter--;
  }

  if(argc < additional_parameter)
  {
    std::cerr << "Error: specify the index to merge into and one index to add." << std::endl;
    return 1;
  }

  std::string base_name = argv[original_parameter];
  std::cout << "Index to update: " << base_name << std::endl;
  
  std::vector<std::string> additional_names;
  
  for(int i = additional_parameter; i < argc; i++)
  {
    std::string additional_name = argv[i];
    std::cout << "Index to add: " << additional_name << std::endl;
    additional_names.push_back(additional_name);
  }
  
  std::cout << "Threads: " << threads << std::endl; 
  std::cout << std::endl;

  std::string parameters_name = base_name + PARAMETERS_EXTENSION;
  Parameters parameters;
  parameters.set(RLCSA_BLOCK_SIZE);
  parameters.set(SAMPLE_RATE);
  parameters.set(SUPPORT_LOCATE);
  parameters.set(SUPPORT_DISPLAY);
  parameters.set(WEIGHTED_SAMPLES);
  parameters.read(parameters_name);
  parameters.print();

  double start = readTimer();
  double megabytes = 0.0;
  
  
  std::cout << "Merging the indexes" << std::endl;
  
  double mark = readTimer();
  std::cout << "Load: " << base_name; std::cout.flush();
  RLCSA* originalIndex = new RLCSA(base_name);
  RLCSABuilder builder(parameters.get(RLCSA_BLOCK_SIZE), parameters.get(SAMPLE_RATE), 0, threads, originalIndex);
  std::cout << " (" << (readTimer() - mark) << " seconds)" << std::endl;
  
  for(std::vector<std::string>::iterator i = additional_names.begin(); i != additional_names.end(); ++i)
  {
    mark = readTimer();
    std::cout << "Increment: " << *i; std::cout.flush();
    builder.insertFromFile(*i);
    std::cout << " (" << (readTimer() - mark) << " seconds)" << std::endl;
  }
  
  std::cout << std::endl;
  megabytes = getRLCSA(builder, base_name);

  double stop = readTimer();
  std::cout << megabytes << " megabytes indexed in " << (stop - start) << " seconds (" << (megabytes / (stop - start)) << " MB/s)." << std::endl;
  std::cout << "Search time:   " << builder.getSearchTime() << " seconds" << std::endl;
  std::cout << "Sort time:     " << builder.getSortTime() << " seconds" << std::endl;
  std::cout << "Merge time:    " << builder.getMergeTime() << " seconds" << std::endl;
  std::cout << "Memory usage:  " << memoryUsage() << " kB" << std::endl;
  std::cout << std::endl;

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x310, %rsp            # imm = 0x310
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x33db0(%rip), %rdi     # 0x38fd0
leaq 0x24e8f(%rip), %rsi     # 0x2a0b6
callq 0x32a0
movq %rax, %rdi
movq 0x33d7a(%rip), %rsi     # 0x38fb0
callq 0x3300
cmpl $0x3, -0x8(%rbp)
jge 0x526f
movq 0x33d88(%rip), %rdi     # 0x38fd0
leaq 0x24e74(%rip), %rsi     # 0x2a0c3
callq 0x32a0
movq %rax, %rdi
movq 0x33d52(%rip), %rsi     # 0x38fb0
callq 0x3300
movl $0x1, -0x4(%rbp)
jmp 0x5d65
movl $0x2, -0x14(%rbp)
movl $0x3, -0x18(%rbp)
movl $0x1, -0x1c(%rbp)
movl $0x1, -0x20(%rbp)
movl -0x8(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jle 0x52e9
movq -0x10(%rbp), %rax
movslq -0x1c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x52e9
movq -0x10(%rbp), %rax
movslq -0x1c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x1, %rdi
callq 0x34a0
movl %eax, -0x24(%rbp)
movl $0x1, -0x28(%rbp)
leaq -0x24(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x6140
movq %rax, %rsi
leaq 0x24f7f(%rip), %rdi     # 0x2a25c
callq 0x6100
movl (%rax), %eax
movl %eax, -0x20(%rbp)
jmp 0x52fb
movl -0x14(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x18(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x8(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x5331
movq 0x33ce6(%rip), %rdi     # 0x38ff0
leaq 0x24df5(%rip), %rsi     # 0x2a106
callq 0x32a0
movq %rax, %rdi
movq 0x33c90(%rip), %rsi     # 0x38fb0
callq 0x3300
movl $0x1, -0x4(%rbp)
jmp 0x5d65
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x188(%rbp)
leaq -0x49(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0x3530
movq -0x188(%rbp), %rsi
movq -0x180(%rbp), %rdx
leaq -0x48(%rbp), %rdi
callq 0x5e30
jmp 0x536d
leaq -0x49(%rbp), %rdi
callq 0x3320
movq 0x33c53(%rip), %rdi     # 0x38fd0
leaq 0x24dbf(%rip), %rsi     # 0x2a143
callq 0x32a0
movq %rax, -0x190(%rbp)
jmp 0x5392
movq -0x190(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3280
movq %rax, -0x198(%rbp)
jmp 0x53ab
movq -0x198(%rbp), %rdi
movq 0x33bf7(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x53c0
leaq -0x78(%rbp), %rdi
callq 0x6180
movl -0x18(%rbp), %eax
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x5507
movq -0x10(%rbp), %rax
movslq -0x7c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x1a8(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x3530
movq -0x1a8(%rbp), %rsi
movq -0x1a0(%rbp), %rdx
leaq -0xa0(%rbp), %rdi
callq 0x5e30
jmp 0x541d
leaq -0xa1(%rbp), %rdi
callq 0x3320
movq 0x33ba0(%rip), %rdi     # 0x38fd0
leaq 0x24d1e(%rip), %rsi     # 0x2a155
callq 0x32a0
movq %rax, -0x1b0(%rbp)
jmp 0x5445
movq -0x1b0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x3280
movq %rax, -0x1b8(%rbp)
jmp 0x5461
movq -0x1b8(%rbp), %rdi
movq 0x33b41(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5476
leaq -0x78(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x61a0
jmp 0x5488
leaq -0xa0(%rbp), %rdi
callq 0x35c8
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x53cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x49(%rbp), %rdi
callq 0x3320
jmp 0x5d71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5d5a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xa1(%rbp), %rdi
callq 0x3320
jmp 0x5d51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x35c8
jmp 0x5d51
movq 0x33ac2(%rip), %rdi     # 0x38fd0
leaq 0x24c4f(%rip), %rsi     # 0x2a164
callq 0x32a0
movq %rax, -0x1c0(%rbp)
jmp 0x5523
movq -0x1c0(%rbp), %rdi
movl -0x20(%rbp), %esi
callq 0x33f0
movq %rax, -0x1c8(%rbp)
jmp 0x553b
movq -0x1c8(%rbp), %rdi
movq 0x33a67(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5550
movq 0x33a79(%rip), %rdi     # 0x38fd0
movq 0x33a52(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5565
leaq 0x33e1c(%rip), %rdx     # 0x39388
leaq -0xc8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x6210
jmp 0x557e
leaq -0xf8(%rbp), %rdi
callq 0x6290
jmp 0x558c
leaq 0x33e75(%rip), %rsi     # 0x39408
leaq -0xf8(%rbp), %rdi
callq 0x240f0
jmp 0x55a1
leaq 0x33e88(%rip), %rsi     # 0x39430
leaq -0xf8(%rbp), %rdi
callq 0x240f0
jmp 0x55b6
leaq 0x33e9b(%rip), %rsi     # 0x39458
leaq -0xf8(%rbp), %rdi
callq 0x240f0
jmp 0x55cb
leaq 0x33eae(%rip), %rsi     # 0x39480
leaq -0xf8(%rbp), %rdi
callq 0x240f0
jmp 0x55e0
leaq 0x33ec1(%rip), %rsi     # 0x394a8
leaq -0xf8(%rbp), %rdi
callq 0x240f0
jmp 0x55f5
leaq -0xf8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x24430
jmp 0x560a
leaq -0xf8(%rbp), %rdi
callq 0x24580
jmp 0x5618
callq 0x263b0
movsd %xmm0, -0x1d0(%rbp)
jmp 0x5627
movsd -0x1d0(%rbp), %xmm0
movsd %xmm0, -0x100(%rbp)
movq $0x0, -0x108(%rbp)
movq 0x33987(%rip), %rdi     # 0x38fd0
leaq 0x24b1e(%rip), %rsi     # 0x2a16e
callq 0x32a0
movq %rax, -0x1d8(%rbp)
jmp 0x565e
movq -0x1d8(%rbp), %rdi
movq 0x33944(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5673
callq 0x263b0
movsd %xmm0, -0x1e0(%rbp)
jmp 0x5682
movsd -0x1e0(%rbp), %xmm0
movsd %xmm0, -0x110(%rbp)
movq 0x33937(%rip), %rdi     # 0x38fd0
leaq 0x24ae2(%rip), %rsi     # 0x2a182
callq 0x32a0
movq %rax, -0x1e8(%rbp)
jmp 0x56ae
movq -0x1e8(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x3280
jmp 0x56c0
movq 0x33909(%rip), %rdi     # 0x38fd0
callq 0x31c0
jmp 0x56ce
movl $0x830, %edi            # imm = 0x830
callq 0x32c0
movq %rax, -0x1f0(%rbp)
jmp 0x56e1
movq -0x1f0(%rbp), %rdi
leaq -0x48(%rbp), %rsi
xorl %edx, %edx
callq 0x76f0
jmp 0x56f5
movq -0x1f0(%rbp), %rax
movq %rax, -0x118(%rbp)
leaq 0x33cfe(%rip), %rsi     # 0x39408
leaq -0xf8(%rbp), %rdi
callq 0x24080
movl %eax, -0x1f4(%rbp)
jmp 0x571e
leaq 0x33d0b(%rip), %rsi     # 0x39430
leaq -0xf8(%rbp), %rdi
callq 0x24080
movl %eax, -0x1f8(%rbp)
jmp 0x5739
movl -0x1f8(%rbp), %edx
movl -0x1f4(%rbp), %esi
movl -0x20(%rbp), %r8d
movq -0x118(%rbp), %r9
leaq -0x160(%rbp), %rdi
xorl %ecx, %ecx
callq 0x13970
jmp 0x5760
movq 0x33869(%rip), %rdi     # 0x38fd0
leaq 0x24a50(%rip), %rsi     # 0x2a1be
callq 0x32a0
movq %rax, -0x200(%rbp)
jmp 0x577c
callq 0x263b0
movsd %xmm0, -0x208(%rbp)
jmp 0x578b
movq -0x200(%rbp), %rdi
movsd -0x208(%rbp), %xmm0
movsd -0x110(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x3560
movq %rax, -0x210(%rbp)
jmp 0x57b4
movq -0x210(%rbp), %rdi
leaq 0x249c7(%rip), %rsi     # 0x2a189
callq 0x32a0
movq %rax, -0x218(%rbp)
jmp 0x57d0
movq -0x218(%rbp), %rdi
movq 0x337d2(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x57e5
leaq -0x78(%rbp), %rdi
callq 0x62b0
movq %rax, -0x168(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x6320
movq %rax, -0x170(%rbp)
leaq -0x168(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x62e0
testb $0x1, %al
jne 0x5821
jmp 0x59ae
callq 0x263b0
movsd %xmm0, -0x220(%rbp)
jmp 0x5830
movsd -0x220(%rbp), %xmm0
movsd %xmm0, -0x110(%rbp)
movq 0x33789(%rip), %rdi     # 0x38fd0
leaq 0x24945(%rip), %rsi     # 0x2a193
callq 0x32a0
movq %rax, -0x228(%rbp)
jmp 0x585c
leaq -0x168(%rbp), %rdi
callq 0x6350
movq -0x228(%rbp), %rdi
movq %rax, %rsi
callq 0x3280
jmp 0x5879
movq 0x33750(%rip), %rdi     # 0x38fd0
callq 0x31c0
jmp 0x5887
leaq -0x168(%rbp), %rdi
callq 0x6350
movq %rax, %rsi
leaq -0x160(%rbp), %rdi
callq 0x13e90
jmp 0x58a4
movq 0x33725(%rip), %rdi     # 0x38fd0
leaq 0x2490c(%rip), %rsi     # 0x2a1be
callq 0x32a0
movq %rax, -0x230(%rbp)
jmp 0x58c0
callq 0x263b0
movsd %xmm0, -0x238(%rbp)
jmp 0x58cf
movq -0x230(%rbp), %rdi
movsd -0x238(%rbp), %xmm0
movsd -0x110(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x3560
movq %rax, -0x240(%rbp)
jmp 0x58f8
movq -0x240(%rbp), %rdi
leaq 0x24883(%rip), %rsi     # 0x2a189
callq 0x32a0
movq %rax, -0x248(%rbp)
jmp 0x5914
movq -0x248(%rbp), %rdi
movq 0x3368e(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5929
jmp 0x592b
leaq -0x168(%rbp), %rdi
callq 0x6370
jmp 0x57f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5d51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5d45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x5d39
movq -0x1f0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
movl $0x830, %esi            # imm = 0x830
callq 0x32d0
jmp 0x5d39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x13ac0
jmp 0x5d39
movq 0x3361b(%rip), %rdi     # 0x38fd0
movq 0x335f4(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x59c3
leaq -0x160(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x5d80
movsd %xmm0, -0x250(%rbp)
jmp 0x59dd
movsd -0x250(%rbp), %xmm0
movsd %xmm0, -0x108(%rbp)
callq 0x263b0
movsd %xmm0, -0x258(%rbp)
jmp 0x59fc
movsd -0x258(%rbp), %xmm0
movsd %xmm0, -0x178(%rbp)
movsd -0x108(%rbp), %xmm0
movq 0x335b5(%rip), %rdi     # 0x38fd0
callq 0x3560
movq %rax, -0x260(%rbp)
jmp 0x5a29
movq -0x260(%rbp), %rdi
leaq 0x24768(%rip), %rsi     # 0x2a19f
callq 0x32a0
movq %rax, -0x268(%rbp)
jmp 0x5a45
movq -0x268(%rbp), %rdi
movsd -0x178(%rbp), %xmm0
movsd -0x100(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x3560
movq %rax, -0x270(%rbp)
jmp 0x5a6e
movq -0x270(%rbp), %rdi
leaq 0x2473a(%rip), %rsi     # 0x2a1b6
callq 0x32a0
movq %rax, -0x278(%rbp)
jmp 0x5a8a
movq -0x278(%rbp), %rdi
movsd -0x108(%rbp), %xmm0
movsd -0x178(%rbp), %xmm1
movsd -0x100(%rbp), %xmm2
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
callq 0x3560
movq %rax, -0x280(%rbp)
jmp 0x5abf
movq -0x280(%rbp), %rdi
leaq 0x246f4(%rip), %rsi     # 0x2a1c1
callq 0x32a0
movq %rax, -0x288(%rbp)
jmp 0x5adb
movq -0x288(%rbp), %rdi
movq 0x334c7(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5af0
movq 0x334d9(%rip), %rdi     # 0x38fd0
leaq 0x246cb(%rip), %rsi     # 0x2a1c9
callq 0x32a0
movq %rax, -0x290(%rbp)
jmp 0x5b0c
leaq -0x160(%rbp), %rdi
callq 0x14bd0
movsd %xmm0, -0x298(%rbp)
jmp 0x5b22
movsd -0x298(%rbp), %xmm0
movq -0x290(%rbp), %rdi
callq 0x3560
movq %rax, -0x2a0(%rbp)
jmp 0x5b3f
movq -0x2a0(%rbp), %rdi
leaq 0x2468c(%rip), %rsi     # 0x2a1d9
callq 0x32a0
movq %rax, -0x2a8(%rbp)
jmp 0x5b5b
movq -0x2a8(%rbp), %rdi
movq 0x33447(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5b70
movq 0x33459(%rip), %rdi     # 0x38fd0
leaq 0x24664(%rip), %rsi     # 0x2a1e2
callq 0x32a0
movq %rax, -0x2b0(%rbp)
jmp 0x5b8c
leaq -0x160(%rbp), %rdi
callq 0x14bf0
movsd %xmm0, -0x2b8(%rbp)
jmp 0x5ba2
movsd -0x2b8(%rbp), %xmm0
movq -0x2b0(%rbp), %rdi
callq 0x3560
movq %rax, -0x2c0(%rbp)
jmp 0x5bbf
movq -0x2c0(%rbp), %rdi
leaq 0x2460c(%rip), %rsi     # 0x2a1d9
callq 0x32a0
movq %rax, -0x2c8(%rbp)
jmp 0x5bdb
movq -0x2c8(%rbp), %rdi
movq 0x333c7(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5bf0
movq 0x333d9(%rip), %rdi     # 0x38fd0
leaq 0x245f4(%rip), %rsi     # 0x2a1f2
callq 0x32a0
movq %rax, -0x2d0(%rbp)
jmp 0x5c0c
leaq -0x160(%rbp), %rdi
callq 0x14c10
movsd %xmm0, -0x2d8(%rbp)
jmp 0x5c22
movsd -0x2d8(%rbp), %xmm0
movq -0x2d0(%rbp), %rdi
callq 0x3560
movq %rax, -0x2e0(%rbp)
jmp 0x5c3f
movq -0x2e0(%rbp), %rdi
leaq 0x2458c(%rip), %rsi     # 0x2a1d9
callq 0x32a0
movq %rax, -0x2e8(%rbp)
jmp 0x5c5b
movq -0x2e8(%rbp), %rdi
movq 0x33347(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5c70
movq 0x33359(%rip), %rdi     # 0x38fd0
leaq 0x24584(%rip), %rsi     # 0x2a202
callq 0x32a0
movq %rax, -0x2f0(%rbp)
jmp 0x5c8c
callq 0x263d0
movl %eax, -0x2f4(%rbp)
jmp 0x5c99
movl -0x2f4(%rbp), %esi
movq -0x2f0(%rbp), %rdi
callq 0x33f0
movq %rax, -0x300(%rbp)
jmp 0x5cb4
movq -0x300(%rbp), %rdi
leaq 0x24550(%rip), %rsi     # 0x2a212
callq 0x32a0
movq %rax, -0x308(%rbp)
jmp 0x5cd0
movq -0x308(%rbp), %rdi
movq 0x332d2(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5ce5
movq 0x332e4(%rip), %rdi     # 0x38fd0
movq 0x332bd(%rip), %rsi     # 0x38fb0
callq 0x3300
jmp 0x5cfa
movl $0x0, -0x4(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x13ac0
leaq -0xf8(%rbp), %rdi
callq 0x6390
leaq -0xc8(%rbp), %rdi
callq 0x35c8
leaq -0x78(%rbp), %rdi
callq 0x63b0
leaq -0x48(%rbp), %rdi
callq 0x35c8
jmp 0x5d65
leaq -0xf8(%rbp), %rdi
callq 0x6390
leaq -0xc8(%rbp), %rdi
callq 0x35c8
leaq -0x78(%rbp), %rdi
callq 0x63b0
leaq -0x48(%rbp), %rdi
callq 0x35c8
jmp 0x5d71
movl -0x4(%rbp), %eax
addq $0x310, %rsp            # imm = 0x310
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x3520
nopw (%rax,%rax)