// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rsi, %r14
movl %edi, %ebp
movq 0x1ae47(%rip), %rdi     # 0x1efd0
leaq 0xff26(%rip), %rsi      # 0x140b6
callq 0x3200
movq %rax, %rdi
callq 0x30f0
cmpl $0x2, %ebp
jg 0x41c5
movq 0x1ae27(%rip), %rdi     # 0x1efd0
leaq 0xff13(%rip), %rsi      # 0x140c3
callq 0x3200
movq %rax, %rdi
callq 0x30f0
pushq $0x1
popq %rax
jmp 0x4705
movq 0x8(%r14), %rdi
cmpb $0x2d, (%rdi)
jne 0x41f2
incq %rdi
callq 0x3350
cmpl $0x2, %eax
pushq $0x1
popq %rcx
cmovgel %eax, %ecx
cmpl $0x40, %ecx
pushq $0x40
popq %rax
cmovll %ecx, %eax
movl %eax, (%rsp)
pushq $0x2
popq %rax
pushq $0x3
jmp 0x41fd
pushq $0x1
popq %rax
movl %eax, (%rsp)
pushq $0x1
popq %rax
pushq $0x2
popq %r15
movq (%r14,%rax,8), %rsi
leaq 0x60(%rsp), %rdi
leaq 0x80(%rsp), %rdx
callq 0x4814
movq 0x1adb4(%rip), %rdi     # 0x1efd0
leaq 0xfee3(%rip), %rsi      # 0x14106
callq 0x3200
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x31f0
movq %rax, %rdi
callq 0x30f0
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %rax
movapd %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movl %ebp, %r13d
leaq 0x80(%rsp), %r12
movq 0x1ad6f(%rip), %rbp     # 0x1efd0
leaq 0xfeb0(%rip), %rbx      # 0x14118
cmpq %r13, %r15
jae 0x42b6
movq (%r14,%r15,8), %rsi
movq %r12, %rdi
leaq 0x10(%rsp), %rdx
callq 0x4814
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x3200
movq %rax, %rdi
movq %r12, %rsi
callq 0x31f0
movq %rax, %rdi
callq 0x30f0
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
callq 0x48de
movq %r12, %rdi
callq 0x3468
incq %r15
jmp 0x4268
movq 0x1ad13(%rip), %rdi     # 0x1efd0
leaq 0xfe63(%rip), %rsi      # 0x14127
callq 0x3200
movl (%rsp), %ebp
movl %ebp, %esi
movq %rax, %rdi
callq 0x3150
movq %rax, %rdi
callq 0x30f0
movq 0x1aceb(%rip), %rdi     # 0x1efd0
callq 0x30f0
leaq 0x1afe7(%rip), %rdx     # 0x1f2d8
leaq 0xc8(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x490a
leaq 0x18(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x1b034(%rip), %rsi     # 0x1f358
leaq 0x10(%rsp), %rdi
callq 0x11258
leaq 0x1b04b(%rip), %rsi     # 0x1f380
leaq 0x10(%rsp), %rdi
callq 0x11258
leaq 0x1b062(%rip), %rsi     # 0x1f3a8
leaq 0x10(%rsp), %rdi
callq 0x11258
leaq 0x1b079(%rip), %rsi     # 0x1f3d0
leaq 0x10(%rsp), %rdi
callq 0x11258
leaq 0x1b090(%rip), %rsi     # 0x1f3f8
leaq 0x10(%rsp), %rdi
callq 0x11258
leaq 0x10(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x114a0
leaq 0x10(%rsp), %rdi
callq 0x1154e
callq 0x11ef8
movsd %xmm0, 0x58(%rsp)
movq 0x1ac30(%rip), %rdi     # 0x1efd0
leaq 0xfd8a(%rip), %rsi      # 0x14131
callq 0x3200
movq %rax, %rdi
callq 0x30f0
callq 0x11ef8
movsd %xmm0, 0x8(%rsp)
movq 0x1ac0a(%rip), %rdi     # 0x1efd0
leaq 0xfd78(%rip), %rsi      # 0x14145
callq 0x3200
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x31f0
movq 0x1abea(%rip), %rdi     # 0x1efd0
callq 0x3160
movl $0x830, %edi            # imm = 0x830
callq 0x3220
movq %rax, %r14
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
xorl %edx, %edx
callq 0x4c9c
leaq 0x1af4a(%rip), %rsi     # 0x1f358
leaq 0x10(%rsp), %rdi
callq 0x11246
movl %eax, %ebx
leaq 0x1af5f(%rip), %rsi     # 0x1f380
leaq 0x10(%rsp), %rdi
callq 0x11246
leaq 0x80(%rsp), %rdi
movl %ebx, %esi
movl %eax, %edx
xorl %ecx, %ecx
movl %ebp, %r8d
movq %r14, %r9
callq 0x9bf4
movq 0x1ab85(%rip), %rdi     # 0x1efd0
leaq 0xfd2f(%rip), %rsi      # 0x14181
callq 0x3200
movq %rax, %rbx
callq 0x11ef8
subsd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x3380
leaq 0xfcd8(%rip), %rsi      # 0x1414c
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x40(%rsp), %rbx
movq 0x1ab40(%rip), %r14     # 0x1efd0
leaq 0x80(%rsp), %r12
leaq 0xfce2(%rip), %r13      # 0x14181
leaq 0xfca6(%rip), %rbp      # 0x1414c
cmpq 0x48(%rsp), %rbx
je 0x451d
callq 0x11ef8
movsd %xmm0, (%rsp)
movq %r14, %rdi
leaq 0xfc95(%rip), %rsi      # 0x14156
callq 0x3200
movq %rax, %rdi
movq %rbx, %rsi
callq 0x31f0
movq %r14, %rdi
callq 0x3160
movq %r12, %rdi
movq %rbx, %rsi
callq 0x9eec
movq %r14, %rdi
movq %r13, %rsi
callq 0x3200
movq %rax, %r15
callq 0x11ef8
subsd (%rsp), %xmm0
movq %r15, %rdi
callq 0x3380
movq %rax, %rdi
movq %rbp, %rsi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
addq $0x20, %rbx
jmp 0x44a6
movq 0x1aaac(%rip), %rdi     # 0x1efd0
callq 0x30f0
leaq 0x80(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x479a
movsd %xmm0, 0x8(%rsp)
callq 0x11ef8
movsd %xmm0, (%rsp)
movq 0x1aa7e(%rip), %rdi     # 0x1efd0
movsd 0x8(%rsp), %xmm0
callq 0x3380
leaq 0xfbfe(%rip), %rsi      # 0x14162
movq %rax, %rdi
callq 0x3200
movsd (%rsp), %xmm0
subsd 0x58(%rsp), %xmm0
movq %rax, %rdi
movsd %xmm0, (%rsp)
callq 0x3380
leaq 0xfbee(%rip), %rsi      # 0x14179
movq %rax, %rdi
callq 0x3200
movsd 0x8(%rsp), %xmm0
divsd (%rsp), %xmm0
movq %rax, %rdi
callq 0x3380
leaq 0xfbd7(%rip), %rsi      # 0x14184
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x1aa0c(%rip), %rdi     # 0x1efd0
leaq 0xfbc1(%rip), %rsi      # 0x1418c
callq 0x3200
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0xa5b6
movq %rbx, %rdi
callq 0x3380
leaq 0xfbad(%rip), %rsi      # 0x1419c
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x1a9ca(%rip), %rdi     # 0x1efd0
leaq 0xfb98(%rip), %rsi      # 0x141a5
callq 0x3200
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0xa5bc
movq %rbx, %rdi
callq 0x3380
leaq 0xfb6b(%rip), %rsi      # 0x1419c
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x1a988(%rip), %rdi     # 0x1efd0
leaq 0xfb66(%rip), %rsi      # 0x141b5
callq 0x3200
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0xa5c2
movq %rbx, %rdi
callq 0x3380
leaq 0xfb29(%rip), %rsi      # 0x1419c
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x1a946(%rip), %rdi     # 0x1efd0
leaq 0xfb34(%rip), %rsi      # 0x141c5
callq 0x3200
movq %rax, %rbx
callq 0x11f0d
movl %eax, %esi
movq %rbx, %rdi
callq 0x3150
leaq 0xfb26(%rip), %rsi      # 0x141d5
movq %rax, %rdi
callq 0x3200
movq %rax, %rdi
callq 0x30f0
movq 0x1a90a(%rip), %rdi     # 0x1efd0
callq 0x30f0
leaq 0x80(%rsp), %rdi
callq 0x9c78
leaq 0x10(%rsp), %rdi
callq 0x496e
leaq 0xc8(%rsp), %rdi
callq 0x3468
leaq 0x40(%rsp), %rdi
callq 0x4942
leaq 0x60(%rsp), %rdi
callq 0x3468
xorl %eax, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x830, %esi            # imm = 0x830
movq %r14, %rdi
callq 0x3230
jmp 0x4767
jmp 0x473e
jmp 0x473e
jmp 0x4745
jmp 0x473e
jmp 0x473e
movq %rax, %rbx
jmp 0x4788
jmp 0x473e
jmp 0x4745
jmp 0x4757
movq %rax, %rbx
jmp 0x4767
jmp 0x4757
movq %rax, %rbx
jmp 0x477e
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
jmp 0x4779
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x9c78
leaq 0x10(%rsp), %rdi
callq 0x496e
leaq 0xc8(%rsp), %rdi
callq 0x3468
leaq 0x40(%rsp), %rdi
callq 0x4942
leaq 0x60(%rsp), %rdi
callq 0x3468
movq %rbx, %rdi
callq 0x3400