// File: sile[P]mphf/mkmphf.cc
// Function: main
int main(int argc, char** argv) {
  if(argc < 3) {
    std::cerr << "Usage: mkmphf [--mapping-loop-limit=<N>] [--hash-code-scale=<D>] [--hash-seed=<N>] <index> <keyset>" << std::endl;
    return 1;
  }

  int param_i=1;
  int loop_limit=32;
  int hash_seed=-1;
  double hash_code_scale=2.09;
  
  for(; param_i < argc; param_i++) {
    if(strncmp(argv[param_i], OPT1"=", strlen(OPT1"="))==0) {
      loop_limit = atoi(argv[param_i]+strlen(OPT1"="));
    } else if (strncmp(argv[param_i], OPT2"=", strlen(OPT2"="))==0) {
      hash_code_scale = atof(argv[param_i]+strlen(OPT2"="));
    } else if (strncmp(argv[param_i], OPT3"=", strlen(OPT3"="))==0) {
      hash_seed = atoi(argv[param_i]+strlen(OPT3"="));
    } else if (strncmp(argv[param_i], "--", 2) != 0) {
      break;
    } else {
      std::cerr << "Usage: mkmphf [--mapping-loop-limit=<N>] [--hash-code-scale=<D>] <index> <keyset>" << std::endl;
      return 1;      
    }
  }

  const char* keyset_filepath = argv[param_i+1];
  const char* index_filepath = argv[param_i];

  std::cerr << "= Initialize" << std::endl;
  MPHF::Generator gen(keyset_filepath, hash_code_scale, hash_seed);
  if(!gen) {
    std::cerr << "Can't open file(or file is empty): " << keyset_filepath << std::endl;
    return 1;    
  }

  std::cerr << "  == key count: " << gen.key_count << std::endl;
  std::cerr << "  == hash value limit: " << gen.hash_value_limit << std::endl;
  std::cerr << "DONE" << std::endl;
  
  std::cerr << "= Mapping Step: " << std::endl;
  int loop_count=0;
  for(; loop_count < loop_limit; loop_count++) {
    std::cerr << " == loop: " << loop_count+1 << '/' << loop_limit << std::endl;
    if(gen.mapping()==true)
      break;
  }
  if(loop_count==loop_limit) {
    std::cerr << "Failure: loop limit exceeded" << std::endl;
    return 1;
  }
  std::cerr << "Done" << std::endl;
    
  std::cerr << "= Assigning Step: " << std::endl;
  gen.assigning();
  std::cerr << "Done" << std::endl;

  std::cerr << "= Ranking Step: " << std::endl;
  gen.ranking();
  std::cerr << "Done" << std::endl;

  std::cerr << "= Save: " << index_filepath << std::endl;
  std::ofstream out(index_filepath);
  if(!out) {
    std::cerr << "Can't open file: " << index_filepath << std::endl;
    return 1;
  }
  gen.save(out);
  std::cerr << "Done" << std::endl;

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x360, %rsp            # imm = 0x360
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x3, -0x8(%rbp)
jge 0x247d
movq 0x6b9a(%rip), %rdi      # 0x8ff0
leaq 0x3bb3(%rip), %rsi      # 0x6010
callq 0x2180
movq %rax, %rdi
movq 0x6b5c(%rip), %rsi      # 0x8fc8
callq 0x21b0
movl $0x1, -0x4(%rbp)
jmp 0x2b3c
movl $0x1, -0x14(%rbp)
movl $0x20, -0x18(%rbp)
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
movsd 0x3b6e(%rip), %xmm0     # 0x6008
movsd %xmm0, -0x28(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x25cd
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x3bb6(%rip), %rsi      # 0x6074
movl $0x15, %edx
callq 0x20e0
cmpl $0x0, %eax
jne 0x24ea
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x15, %rdi
callq 0x2280
movl %eax, -0x18(%rbp)
jmp 0x25bd
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x3b8d(%rip), %rsi      # 0x608a
movl $0x12, %edx
callq 0x20e0
cmpl $0x0, %eax
jne 0x252b
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x12, %rdi
callq 0x21f0
movsd %xmm0, -0x28(%rbp)
jmp 0x25bb
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x3b5f(%rip), %rsi      # 0x609d
movl $0xc, %edx
callq 0x20e0
cmpl $0x0, %eax
jne 0x2567
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq $0xc, %rdi
callq 0x2280
movl %eax, -0x1c(%rbp)
jmp 0x25b9
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x3b30(%rip), %rsi      # 0x60aa
movl $0x2, %edx
callq 0x20e0
cmpl $0x0, %eax
je 0x258b
jmp 0x25cd
movq 0x6a5e(%rip), %rdi      # 0x8ff0
leaq 0x3b14(%rip), %rsi      # 0x60ad
callq 0x2180
movq %rax, %rdi
movq 0x6a20(%rip), %rsi      # 0x8fc8
callq 0x21b0
movl $0x1, -0x4(%rbp)
jmp 0x2b3c
jmp 0x25bb
jmp 0x25bd
jmp 0x25bf
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x249f
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq 0x8(%rax,%rcx,8), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
movq 0x69fb(%rip), %rdi      # 0x8ff0
leaq 0x3b03(%rip), %rsi      # 0x60ff
callq 0x2180
movq %rax, %rdi
movq 0x69bd(%rip), %rsi      # 0x8fc8
callq 0x21b0
movq -0x30(%rbp), %rsi
movsd -0x28(%rbp), %xmm0
movl -0x1c(%rbp), %edx
leaq -0x68(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0x2b60
movq -0x290(%rbp), %rdi
callq 0x2c40
movb %al, -0x281(%rbp)
jmp 0x2640
movb -0x281(%rbp), %al
testb $0x1, %al
jne 0x26ba
jmp 0x264c
movq 0x699d(%rip), %rdi      # 0x8ff0
leaq 0x3ab2(%rip), %rsi      # 0x610c
callq 0x2180
movq %rax, -0x298(%rbp)
jmp 0x2668
movq -0x298(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x2180
movq %rax, -0x2a0(%rbp)
jmp 0x2681
movq -0x2a0(%rbp), %rdi
movq 0x6939(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x2696
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0x2b26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x2b31
movq 0x692f(%rip), %rdi      # 0x8ff0
leaq 0x3a68(%rip), %rsi      # 0x6130
callq 0x2180
movq %rax, -0x2a8(%rbp)
jmp 0x26d6
movq -0x2a8(%rbp), %rdi
movl -0x40(%rbp), %esi
callq 0x2230
movq %rax, -0x2b0(%rbp)
jmp 0x26ee
movq -0x2b0(%rbp), %rdi
movq 0x68cc(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x2703
movq 0x68e6(%rip), %rdi      # 0x8ff0
leaq 0x3a30(%rip), %rsi      # 0x6141
callq 0x2180
movq %rax, -0x2b8(%rbp)
jmp 0x271f
movq -0x2b8(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0x2230
movq %rax, -0x2c0(%rbp)
jmp 0x2737
movq -0x2c0(%rbp), %rdi
movq 0x6883(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x274c
movq 0x689d(%rip), %rdi      # 0x8ff0
leaq 0x39ff(%rip), %rsi      # 0x6159
callq 0x2180
movq %rax, -0x2c8(%rbp)
jmp 0x2768
movq -0x2c8(%rbp), %rdi
movq 0x6852(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x277d
movq 0x686c(%rip), %rdi      # 0x8ff0
leaq 0x39d3(%rip), %rsi      # 0x615e
callq 0x2180
movq %rax, -0x2d0(%rbp)
jmp 0x2799
movq -0x2d0(%rbp), %rdi
movq 0x6821(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x27ae
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x2871
movq 0x6828(%rip), %rdi      # 0x8ff0
leaq 0x39a0(%rip), %rsi      # 0x616f
callq 0x2180
movq %rax, -0x2d8(%rbp)
jmp 0x27dd
movq -0x2d8(%rbp), %rdi
movl -0x7c(%rbp), %esi
incl %esi
callq 0x22a0
movq %rax, -0x2e0(%rbp)
jmp 0x27f7
movq -0x2e0(%rbp), %rdi
movl $0x2f, %esi
callq 0x21e0
movq %rax, -0x2e8(%rbp)
jmp 0x2811
movq -0x2e8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x22a0
movq %rax, -0x2f0(%rbp)
jmp 0x2829
movq -0x2f0(%rbp), %rdi
movq 0x6791(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x283e
leaq -0x68(%rbp), %rdi
callq 0x2c60
movb %al, -0x2f1(%rbp)
jmp 0x284f
movb -0x2f1(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x2861
jmp 0x2871
jmp 0x2863
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x27b5
movl -0x7c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x28bd
movq 0x6770(%rip), %rdi      # 0x8ff0
leaq 0x38f3(%rip), %rsi      # 0x617a
callq 0x2180
movq %rax, -0x300(%rbp)
jmp 0x2895
movq -0x300(%rbp), %rdi
movq 0x6725(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x28aa
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0x2b26
movq 0x672c(%rip), %rdi      # 0x8ff0
leaq 0x38cc(%rip), %rsi      # 0x6197
callq 0x2180
movq %rax, -0x308(%rbp)
jmp 0x28d9
movq -0x308(%rbp), %rdi
movq 0x66e1(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x28ee
movq 0x66fb(%rip), %rdi      # 0x8ff0
leaq 0x38a0(%rip), %rsi      # 0x619c
callq 0x2180
movq %rax, -0x310(%rbp)
jmp 0x290a
movq -0x310(%rbp), %rdi
movq 0x66b0(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x291f
leaq -0x68(%rbp), %rdi
callq 0x2ca0
jmp 0x292a
movq 0x66bf(%rip), %rdi      # 0x8ff0
leaq 0x385f(%rip), %rsi      # 0x6197
callq 0x2180
movq %rax, -0x318(%rbp)
jmp 0x2946
movq -0x318(%rbp), %rdi
movq 0x6674(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x295b
movq 0x668e(%rip), %rdi      # 0x8ff0
leaq 0x3846(%rip), %rsi      # 0x61af
callq 0x2180
movq %rax, -0x320(%rbp)
jmp 0x2977
movq -0x320(%rbp), %rdi
movq 0x6643(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x298c
leaq -0x68(%rbp), %rdi
callq 0x30f0
jmp 0x2997
movq 0x6652(%rip), %rdi      # 0x8ff0
leaq 0x37f2(%rip), %rsi      # 0x6197
callq 0x2180
movq %rax, -0x328(%rbp)
jmp 0x29b3
movq -0x328(%rbp), %rdi
movq 0x6607(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x29c8
movq 0x6621(%rip), %rdi      # 0x8ff0
leaq 0x37ea(%rip), %rsi      # 0x61c0
callq 0x2180
movq %rax, -0x330(%rbp)
jmp 0x29e4
movq -0x330(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x2180
movq %rax, -0x338(%rbp)
jmp 0x29fd
movq -0x338(%rbp), %rdi
movq 0x65bd(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x2a12
movq -0x38(%rbp), %rsi
leaq -0x280(%rbp), %rdi
movl $0x10, %edx
callq 0x21d0
jmp 0x2a29
movq -0x280(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x280(%rbp,%rax), %rdi
callq 0x20d0
movb %al, -0x339(%rbp)
jmp 0x2a49
movb -0x339(%rbp), %al
testb $0x1, %al
jne 0x2a55
jmp 0x2ac9
movq 0x6594(%rip), %rdi      # 0x8ff0
leaq 0x3766(%rip), %rsi      # 0x61c9
callq 0x2180
movq %rax, -0x348(%rbp)
jmp 0x2a71
movq -0x348(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x2180
movq %rax, -0x350(%rbp)
jmp 0x2a8a
movq -0x350(%rbp), %rdi
movq 0x6530(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x2a9f
movl $0x1, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
jmp 0x2b1a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x2260
jmp 0x2b31
leaq -0x68(%rbp), %rdi
leaq -0x280(%rbp), %rsi
callq 0x3110
jmp 0x2adb
movq 0x650e(%rip), %rdi      # 0x8ff0
leaq 0x36ae(%rip), %rsi      # 0x6197
callq 0x2180
movq %rax, -0x358(%rbp)
jmp 0x2af7
movq -0x358(%rbp), %rdi
movq 0x64c3(%rip), %rsi      # 0x8fc8
callq 0x21b0
jmp 0x2b0c
movl $0x0, -0x4(%rbp)
movl $0x1, -0x78(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x2260
leaq -0x68(%rbp), %rdi
callq 0x3260
jmp 0x2b3c
leaq -0x68(%rbp), %rdi
callq 0x3260
jmp 0x2b48
movl -0x4(%rbp), %eax
addq $0x360, %rsp            # imm = 0x360
popq %rbp
retq
movq -0x70(%rbp), %rdi
callq 0x22b0
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)