// File: adamnovak[P]rlcsa/build_rlcsa.cpp
// Function: main
int
main(int argc, char** argv)
{
  try {
    std::cout << "RLCSA builder" << std::endl;
    if(argc < 2)
    {
      std::cout << "Usage: build_rlcsa base_name [threads]" << std::endl;
      return 1;
    }

    std::string base_name = argv[1];
    int threads = 1;
    if(argc > 2)
    {
      threads = std::max(threads, atoi(argv[2]));
      threads = std::min(threads, MAX_THREADS);
    }
    std::cout << "Base name: " << base_name << std::endl;
    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();
    std::ifstream input(base_name.c_str(), std::ios_base::binary);
    if(!input)
    {
      std::cerr << "Error opening input file " << base_name << "!" << std::endl;
      return 2;
    }
    usint size = fileSize(input);
    if(size <= 0)
    {
      std::cerr << "Error: Input file is empty!" << std::endl;
      input.close();
      return 3;
    }
    uchar* data = new uchar[size];
    input.read((char*)data, size);
    input.close();

    RLCSA rlcsa(data, size, parameters.get(RLCSA_BLOCK_SIZE), parameters.get(SAMPLE_RATE), threads, true);
    data = 0; // RLCSA constructor deleted the data!
    if(!(rlcsa.isOk())) { return 4; }
    rlcsa.printInfo();
    rlcsa.reportSize(true);
    rlcsa.writeTo(base_name);
    double total = readTimer() - start;

    double megabytes = size / (double)MEGABYTE;
    std::cout << "Indexed " << megabytes << " megabytes in " << total << " seconds (" << (megabytes / total) << " MB/s)." << std::endl;
    std::cout << "Memory: " << memoryUsage() << " kB" << std::endl;
    std::cout << std::endl;

    return 0;
  } catch(std::bad_alloc e) {
    std::cerr << "Uncaught exception in build_rlcsa!" << std::endl;
    throw e;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc30, %rsp            # imm = 0xC30
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq 0x323a8(%rip), %rdi     # 0x36fc8
leaq 0x2348f(%rip), %rsi     # 0x280b6
callq 0x3290
movq %rax, -0xb10(%rbp)
jmp 0x4c35
movq -0xb10(%rbp), %rdi
movq 0x3234d(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4c4a
cmpl $0x2, -0x8(%rbp)
jge 0x4c9e
movq 0x32371(%rip), %rdi     # 0x36fc8
leaq 0x23466(%rip), %rsi     # 0x280c4
callq 0x3290
movq %rax, -0xb18(%rbp)
jmp 0x4c6c
movq -0xb18(%rbp), %rdi
movq 0x32316(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4c81
movl $0x1, -0x4(%rbp)
jmp 0x54c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x53fc
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xb28(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0xb20(%rbp)
callq 0x3530
movq -0xb28(%rbp), %rsi
movq -0xb20(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0x54f0
jmp 0x4cd6
leaq -0x41(%rbp), %rdi
callq 0x3310
movl $0x1, -0x48(%rbp)
cmpl $0x2, -0x8(%rbp)
jle 0x4d74
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x34a0
movl %eax, -0x4c(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x4c(%rbp), %rsi
callq 0x57c0
movq %rax, -0xb30(%rbp)
jmp 0x4d16
movq -0xb30(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
leaq 0x23493(%rip), %rsi     # 0x281bc
leaq -0x48(%rbp), %rdi
callq 0x5800
movq %rax, -0xb38(%rbp)
jmp 0x4d3b
movq -0xb38(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
jmp 0x4d74
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x41(%rbp), %rdi
callq 0x3310
jmp 0x53fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x53f3
movq 0x3224d(%rip), %rdi     # 0x36fc8
leaq 0x23369(%rip), %rsi     # 0x280eb
callq 0x3290
movq %rax, -0xb40(%rbp)
jmp 0x4d90
movq -0xb40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x3270
movq %rax, -0xb48(%rbp)
jmp 0x4da9
movq -0xb48(%rbp), %rdi
movq 0x321d9(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4dbe
movq 0x32203(%rip), %rdi     # 0x36fc8
leaq 0x2332b(%rip), %rsi     # 0x280f7
callq 0x3290
movq %rax, -0xb50(%rbp)
jmp 0x4dda
movq -0xb50(%rbp), %rdi
movl -0x48(%rbp), %esi
callq 0x3500
movq %rax, -0xb58(%rbp)
jmp 0x4df2
movq -0xb58(%rbp), %rdi
movq 0x32190(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4e07
movq 0x321ba(%rip), %rdi     # 0x36fc8
movq 0x3217b(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4e1c
leaq 0x3256d(%rip), %rdx     # 0x37390
leaq -0x70(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x5840
jmp 0x4e32
leaq -0xa0(%rbp), %rdi
callq 0x58c0
jmp 0x4e40
leaq 0x325c9(%rip), %rsi     # 0x37410
leaq -0xa0(%rbp), %rdi
callq 0x20d60
jmp 0x4e55
leaq 0x325dc(%rip), %rsi     # 0x37438
leaq -0xa0(%rbp), %rdi
callq 0x20d60
jmp 0x4e6a
leaq 0x325ef(%rip), %rsi     # 0x37460
leaq -0xa0(%rbp), %rdi
callq 0x20d60
jmp 0x4e7f
leaq 0x32602(%rip), %rsi     # 0x37488
leaq -0xa0(%rbp), %rdi
callq 0x20d60
jmp 0x4e94
leaq 0x32615(%rip), %rsi     # 0x374b0
leaq -0xa0(%rbp), %rdi
callq 0x20d60
jmp 0x4ea9
leaq -0xa0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x210a0
jmp 0x4ebb
leaq -0xa0(%rbp), %rdi
callq 0x211f0
jmp 0x4ec9
callq 0x23020
movsd %xmm0, -0xb60(%rbp)
jmp 0x4ed8
movsd -0xb60(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x3120
movq %rax, %rsi
leaq -0x2b0(%rbp), %rdi
movl $0x4, %edx
callq 0x3550
jmp 0x4f07
movq -0x2b0(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x2b0(%rbp,%rax), %rdi
callq 0x3150
movb %al, -0xb61(%rbp)
jmp 0x4f27
movb -0xb61(%rbp), %al
testb $0x1, %al
jne 0x4f36
jmp 0x4fe5
movq 0x320b3(%rip), %rdi     # 0x36ff0
leaq 0x231bd(%rip), %rsi     # 0x28101
callq 0x3290
movq %rax, -0xb70(%rbp)
jmp 0x4f52
movq -0xb70(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x3270
movq %rax, -0xb78(%rbp)
jmp 0x4f6b
movq -0xb78(%rbp), %rdi
leaq 0x2376f(%rip), %rsi     # 0x286e8
callq 0x3290
movq %rax, -0xb80(%rbp)
jmp 0x4f87
movq -0xb80(%rbp), %rdi
movq 0x31ffb(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x4f9c
movl $0x2, -0x4(%rbp)
movl $0x1, -0x2b4(%rbp)
jmp 0x53a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x53ea
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x53de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0x53d2
leaq -0x2b0(%rbp), %rdi
callq 0x22a80
movq %rax, -0xb88(%rbp)
jmp 0x4ffa
movq -0xb88(%rbp), %rax
movl %eax, -0x2b8(%rbp)
cmpl $0x0, -0x2b8(%rbp)
ja 0x5065
movq 0x31fd9(%rip), %rdi     # 0x36ff0
leaq 0x230fd(%rip), %rsi     # 0x2811b
callq 0x3290
movq %rax, -0xb90(%rbp)
jmp 0x502c
movq -0xb90(%rbp), %rdi
movq 0x31f56(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x5041
leaq -0x2b0(%rbp), %rdi
callq 0x30b0
jmp 0x504f
movl $0x3, -0x4(%rbp)
movl $0x1, -0x2b4(%rbp)
jmp 0x53a3
movl -0x2b8(%rbp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, -0xb98(%rbp)
jmp 0x507b
movq -0xb98(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movq -0x2c0(%rbp), %rsi
movl -0x2b8(%rbp), %eax
movl %eax, %edx
leaq -0x2b0(%rbp), %rdi
callq 0x33b0
jmp 0x50a6
leaq -0x2b0(%rbp), %rdi
callq 0x30b0
jmp 0x50b4
movq -0x2c0(%rbp), %rax
movq %rax, -0xba8(%rbp)
movl -0x2b8(%rbp), %eax
movl %eax, -0xba0(%rbp)
leaq 0x3233b(%rip), %rsi     # 0x37410
leaq -0xa0(%rbp), %rdi
callq 0x20cf0
movl %eax, -0xb9c(%rbp)
jmp 0x50e9
leaq 0x32348(%rip), %rsi     # 0x37438
leaq -0xa0(%rbp), %rdi
callq 0x20cf0
movl %eax, -0xbac(%rbp)
jmp 0x5104
movl -0xbac(%rbp), %r8d
movl -0xb9c(%rbp), %ecx
movl -0xba0(%rbp), %edx
movq -0xba8(%rbp), %rsi
movl -0x48(%rbp), %r9d
movq %rsp, %rax
movl $0x1, (%rax)
leaq -0xaf0(%rbp), %rdi
callq 0x67d0
jmp 0x5139
movq $0x0, -0x2c0(%rbp)
leaq -0xaf0(%rbp), %rdi
callq 0x58e0
movb %al, -0xbad(%rbp)
jmp 0x5158
movb -0xbad(%rbp), %al
testb $0x1, %al
jne 0x5197
jmp 0x5164
movl $0x4, -0x4(%rbp)
movl $0x1, -0x2b4(%rbp)
jmp 0x5397
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xaf0(%rbp), %rdi
callq 0x8250
jmp 0x53d2
leaq -0xaf0(%rbp), %rdi
callq 0xb0b0
jmp 0x51a5
leaq -0xaf0(%rbp), %rdi
movl $0x1, %esi
callq 0xae40
jmp 0x51b8
leaq -0xaf0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x8370
jmp 0x51ca
callq 0x23020
movsd %xmm0, -0xbb8(%rbp)
jmp 0x51d9
movsd -0xbb8(%rbp), %xmm0
movsd -0xa8(%rbp), %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0xaf8(%rbp)
movl -0x2b8(%rbp), %eax
cvtsi2sd %rax, %xmm0
movsd 0x22e00(%rip), %xmm1    # 0x28008
mulsd %xmm1, %xmm0
movsd %xmm0, -0xb00(%rbp)
movq 0x31dad(%rip), %rdi     # 0x36fc8
leaq 0x22f15(%rip), %rsi     # 0x28137
callq 0x3290
movq %rax, -0xbc0(%rbp)
jmp 0x5230
movq -0xbc0(%rbp), %rdi
movsd -0xb00(%rbp), %xmm0
callq 0x3560
movq %rax, -0xbc8(%rbp)
jmp 0x524d
movq -0xbc8(%rbp), %rdi
leaq 0x22ee5(%rip), %rsi     # 0x28140
callq 0x3290
movq %rax, -0xbd0(%rbp)
jmp 0x5269
movq -0xbd0(%rbp), %rdi
movsd -0xaf8(%rbp), %xmm0
callq 0x3560
movq %rax, -0xbd8(%rbp)
jmp 0x5286
movq -0xbd8(%rbp), %rdi
leaq 0x22ebb(%rip), %rsi     # 0x2814f
callq 0x3290
movq %rax, -0xbe0(%rbp)
jmp 0x52a2
movq -0xbe0(%rbp), %rdi
movsd -0xb00(%rbp), %xmm0
movsd -0xaf8(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x3560
movq %rax, -0xbe8(%rbp)
jmp 0x52cb
movq -0xbe8(%rbp), %rdi
leaq 0x22e81(%rip), %rsi     # 0x2815a
callq 0x3290
movq %rax, -0xbf0(%rbp)
jmp 0x52e7
movq -0xbf0(%rbp), %rdi
movq 0x31c9b(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x52fc
movq 0x31cc5(%rip), %rdi     # 0x36fc8
leaq 0x22e58(%rip), %rsi     # 0x28162
callq 0x3290
movq %rax, -0xbf8(%rbp)
jmp 0x5318
callq 0x23040
movl %eax, -0xbfc(%rbp)
jmp 0x5325
movl -0xbfc(%rbp), %esi
movq -0xbf8(%rbp), %rdi
callq 0x33f0
movq %rax, -0xc08(%rbp)
jmp 0x5340
movq -0xc08(%rbp), %rdi
leaq 0x22e1d(%rip), %rsi     # 0x2816b
callq 0x3290
movq %rax, -0xc10(%rbp)
jmp 0x535c
movq -0xc10(%rbp), %rdi
movq 0x31c26(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x5371
movq 0x31c50(%rip), %rdi     # 0x36fc8
movq 0x31c11(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x5386
movl $0x0, -0x4(%rbp)
movl $0x1, -0x2b4(%rbp)
leaq -0xaf0(%rbp), %rdi
callq 0x8250
leaq -0x2b0(%rbp), %rdi
callq 0x30d0
leaq -0xa0(%rbp), %rdi
callq 0x5900
leaq -0x70(%rbp), %rdi
callq 0x35c8
leaq -0x40(%rbp), %rdi
callq 0x35c8
jmp 0x54c5
leaq -0x2b0(%rbp), %rdi
callq 0x30d0
leaq -0xa0(%rbp), %rdi
callq 0x5900
leaq -0x70(%rbp), %rdi
callq 0x35c8
leaq -0x40(%rbp), %rdi
callq 0x35c8
movl -0x1c(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x54d1
movq -0x18(%rbp), %rdi
movq %rdi, -0xc20(%rbp)
callq 0x3390
movq %rax, %rsi
leaq -0xb08(%rbp), %rdi
callq 0x5920
movq -0xc20(%rbp), %rdi
callq 0x3110
movq 0x31bb2(%rip), %rdi     # 0x36ff0
leaq 0x22d2a(%rip), %rsi     # 0x2816f
callq 0x3290
movq %rax, -0xc18(%rbp)
jmp 0x5453
movq -0xc18(%rbp), %rdi
movq 0x31b2f(%rip), %rsi     # 0x36f90
callq 0x32f0
jmp 0x5468
movl $0x8, %edi
callq 0x3160
movq %rax, %rdi
movq %rdi, -0xc28(%rbp)
leaq -0xb08(%rbp), %rsi
callq 0x5920
movq -0xc28(%rbp), %rdi
movq 0x31b3a(%rip), %rsi     # 0x36fd0
movq 0x31b0b(%rip), %rdx     # 0x36fa8
callq 0x34f0
jmp 0x54e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0xb08(%rbp), %rdi
callq 0x35d0
callq 0x34e0
jmp 0x54c3
jmp 0x54d1
movl -0x4(%rbp), %eax
addq $0xc30, %rsp            # imm = 0xC30
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x3520
movq %rax, %rdi
callq 0x5960
nopw %cs:(%rax,%rax)
nopl (%rax)