// File: sile[P]mphf/test_mphf.cc
// Function: main
int main(int argc, char** argv) {
  if(argc != 2) {
    std::cerr << "Usage: test_mphf <index>" << std::endl;
    return 1;
  }

  const char* index_filepath = argv[1];
  
  MPHF::Hash hash(index_filepath);
  if(!hash) {
    std::cerr << "Can't open file: " << index_filepath << std::endl;
    return 1;
  }
    
  std::string line;
  std::vector<unsigned> hash_values;

  std::cerr << "= Read keyset and calculate hash values:" << std::endl;
  while(std::getline(std::cin, line)) 
    hash_values.push_back(hash.mphf(line.c_str()));
  std::cerr << "  == read key count: " << hash_values.size() << std::endl;
  std::cerr << "DONE" << std::endl;
  
  std::cerr << "= Uniqueness check: " << std::endl;
  std::sort(hash_values.begin(), hash_values.end());
  std::vector<unsigned>::const_iterator end = std::unique(hash_values.begin(), hash_values.end());
  if(end == hash_values.end()) {
    std::cerr << "  == OK" << std::endl;
  } else {
    unsigned dup_rate = 100 - (((end-hash_values.begin())*100)/hash_values.size());
    std::cerr << "  == failure: duplicate rate is " << dup_rate << "%" << std::endl;
  }
  std::cerr << "DONE" << std::endl;

  std::cerr << "= Minimalness check: " << std::endl;
  if(hash_values.back() == hash_values.size()-1)
    std::cerr << "  == OK" << std::endl;
  else
    std::cerr << "  == failure" << std::endl;
  std::cerr << "DONE" << std::endl;

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x135d
movq 0x6cba(%rip), %rdi      # 0x7ff0
leaq 0x3cc7(%rip), %rsi      # 0x5004
callq 0x1100
movq %rax, %rdi
movq 0x6c74(%rip), %rsi      # 0x7fc0
callq 0x1130
movl $0x1, -0x4(%rbp)
jmp 0x18f6
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x50(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x1910
movq -0xf8(%rbp), %rdi
callq 0x1940
movb %al, -0xe9(%rbp)
jmp 0x1391
movb -0xe9(%rbp), %al
testb $0x1, %al
jne 0x140b
jmp 0x139d
movq 0x6c4c(%rip), %rdi      # 0x7ff0
leaq 0x3c72(%rip), %rsi      # 0x501d
callq 0x1100
movq %rax, -0x100(%rbp)
jmp 0x13b9
movq -0x100(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x1100
movq %rax, -0x108(%rbp)
jmp 0x13d2
movq -0x108(%rbp), %rdi
movq 0x6be0(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x13e7
movl $0x1, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
jmp 0x18e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
jmp 0x18eb
leaq -0x80(%rbp), %rdi
callq 0x1160
leaq -0x98(%rbp), %rdi
callq 0x1960
movq 0x6bc9(%rip), %rdi      # 0x7ff0
leaq 0x3c01(%rip), %rsi      # 0x502f
callq 0x1100
movq %rax, -0x110(%rbp)
jmp 0x143c
movq -0x110(%rbp), %rdi
movq 0x6b76(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x1451
jmp 0x1453
movq 0x6b7e(%rip), %rdi      # 0x7fd8
leaq -0x80(%rbp), %rsi
callq 0x1030
movq %rax, -0x118(%rbp)
jmp 0x146c
movq -0x118(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x1140
movb %al, -0x119(%rbp)
jmp 0x148a
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0x1496
jmp 0x14ff
leaq -0x80(%rbp), %rdi
callq 0x1080
movq %rax, %rsi
leaq -0x50(%rbp), %rdi
callq 0x19b0
movl %eax, -0x120(%rbp)
jmp 0x14b3
movl -0x120(%rbp), %eax
movl %eax, -0x9c(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0x1980
jmp 0x14d4
jmp 0x1453
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x1bf0
leaq -0x80(%rbp), %rdi
callq 0x10c0
jmp 0x18eb
movq 0x6aea(%rip), %rdi      # 0x7ff0
leaq 0x3b4b(%rip), %rsi      # 0x5058
callq 0x1100
movq %rax, -0x128(%rbp)
jmp 0x151b
leaq -0x98(%rbp), %rdi
callq 0x19f0
movq -0x128(%rbp), %rdi
movq %rax, %rsi
callq 0x1040
movq %rax, -0x130(%rbp)
jmp 0x153f
movq -0x130(%rbp), %rdi
movq 0x6a73(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x1554
movq 0x6a95(%rip), %rdi      # 0x7ff0
leaq 0x3b0c(%rip), %rsi      # 0x506e
callq 0x1100
movq %rax, -0x138(%rbp)
jmp 0x1570
movq -0x138(%rbp), %rdi
movq 0x6a42(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x1585
movq 0x6a64(%rip), %rdi      # 0x7ff0
leaq 0x3ae0(%rip), %rsi      # 0x5073
callq 0x1100
movq %rax, -0x140(%rbp)
jmp 0x15a1
movq -0x140(%rbp), %rdi
movq 0x6a11(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x15b6
leaq -0x98(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x1a50
movq -0x148(%rbp), %rdi
movq %rax, -0xa8(%rbp)
callq 0x1a80
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
callq 0x1a10
jmp 0x15f8
leaq -0x98(%rbp), %rdi
movq %rdi, -0x158(%rbp)
callq 0x1a50
movq -0x158(%rbp), %rdi
movq %rax, -0xc8(%rbp)
callq 0x1a80
movq %rax, -0xd0(%rbp)
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
callq 0x1ab0
movq %rax, -0x150(%rbp)
jmp 0x1641
movq -0x150(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x1af0
leaq -0x98(%rbp), %rdi
callq 0x1a80
movq %rax, -0xd8(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x1b30
testb $0x1, %al
jne 0x168e
jmp 0x16c4
movq 0x695b(%rip), %rdi      # 0x7ff0
leaq 0x39ec(%rip), %rsi      # 0x5088
callq 0x1100
movq %rax, -0x160(%rbp)
jmp 0x16aa
movq -0x160(%rbp), %rdi
movq 0x6908(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x16bf
jmp 0x1790
leaq -0x98(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x1a50
movq %rax, -0xe8(%rbp)
leaq -0xb8(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1b70
movq -0x178(%rbp), %rdi
imulq $0x64, %rax, %rax
movq %rax, -0x170(%rbp)
callq 0x19f0
movq %rax, %rcx
movq -0x170(%rbp), %rax
xorl %edx, %edx
divq %rcx
movl %eax, %ecx
movl $0x64, %eax
subl %ecx, %eax
movl %eax, -0xdc(%rbp)
movq 0x68c3(%rip), %rdi      # 0x7ff0
leaq 0x395c(%rip), %rsi      # 0x5090
callq 0x1100
movq %rax, -0x168(%rbp)
jmp 0x1742
movq -0x168(%rbp), %rdi
movl -0xdc(%rbp), %esi
callq 0x1150
movq %rax, -0x180(%rbp)
jmp 0x175d
movq -0x180(%rbp), %rdi
leaq 0x3946(%rip), %rsi      # 0x50b1
callq 0x1100
movq %rax, -0x188(%rbp)
jmp 0x1779
movq -0x188(%rbp), %rdi
movq 0x6839(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x178e
jmp 0x1790
movq 0x6859(%rip), %rdi      # 0x7ff0
leaq 0x38d0(%rip), %rsi      # 0x506e
callq 0x1100
movq %rax, -0x190(%rbp)
jmp 0x17ac
movq -0x190(%rbp), %rdi
movq 0x6806(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x17c1
movq 0x6828(%rip), %rdi      # 0x7ff0
leaq 0x38e4(%rip), %rsi      # 0x50b3
callq 0x1100
movq %rax, -0x198(%rbp)
jmp 0x17dd
movq -0x198(%rbp), %rdi
movq 0x67d5(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x17f2
leaq -0x98(%rbp), %rdi
callq 0x1bb0
movl (%rax), %eax
movq %rax, -0x1a0(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x19f0
movq %rax, %rcx
movq -0x1a0(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0x1859
movq 0x67c3(%rip), %rdi      # 0x7ff0
leaq 0x3854(%rip), %rsi      # 0x5088
callq 0x1100
movq %rax, -0x1a8(%rbp)
jmp 0x1842
movq -0x1a8(%rbp), %rdi
movq 0x6770(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x1857
jmp 0x188c
movq 0x6790(%rip), %rdi      # 0x7ff0
leaq 0x3862(%rip), %rsi      # 0x50c9
callq 0x1100
movq %rax, -0x1b0(%rbp)
jmp 0x1875
movq -0x1b0(%rbp), %rdi
movq 0x673d(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x188a
jmp 0x188c
movq 0x675d(%rip), %rdi      # 0x7ff0
leaq 0x37d4(%rip), %rsi      # 0x506e
callq 0x1100
movq %rax, -0x1b8(%rbp)
jmp 0x18a8
movq -0x1b8(%rbp), %rdi
movq 0x670a(%rip), %rsi      # 0x7fc0
callq 0x1130
jmp 0x18bd
movl $0x0, -0x4(%rbp)
movl $0x1, -0x60(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x1bf0
leaq -0x80(%rbp), %rdi
callq 0x10c0
leaq -0x50(%rbp), %rdi
callq 0x1c50
jmp 0x18f6
leaq -0x50(%rbp), %rdi
callq 0x1c50
jmp 0x1902
movl -0x4(%rbp), %eax
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x11a0
nopl (%rax,%rax)