// File: lemire[P]fastscancount/benchmark/counters.cpp
// Function: main
int main(int argc, char *argv[]) {
  // A very naive way to process arguments, 
  // but it's ok unless we need to extend it substantially.
  if (argc != 1) {
    if (argc != 7) {
      usage("");
      return EXIT_FAILURE; 
    }
    std::string postings_file, queries_file;
    int threshold = -1;
    for (int i = 1; i < argc; ++i) {
      if (std::string(argv[i]) == "--postings") {
        postings_file = argv[++i];
      } else if (std::string(argv[i]) == "--queries") {
        queries_file = argv[++i];
      } else if (std::string(argv[i]) == "--threshold") {
        threshold = std::atoi(argv[++i]);
      }
    }
    if (postings_file.empty() || queries_file.empty() || threshold < 0) {
      usage("Specify queries, postings, and the threshold!");
      return EXIT_FAILURE; 
    }
    std::vector<uint32_t> tmp; 
    std::vector<std::vector<uint32_t>> data;
    {
      MaropuGapReader drdr(postings_file);
      if (!drdr.open()) {
        usage("Cannot open: " + postings_file);
        return EXIT_FAILURE; 
      }
      while (drdr.loadIntegers(tmp)) {
        data.push_back(tmp);
      }
    }
    std::vector<std::vector<uint32_t>> queries;
    {
      MaropuGapReader qrdr(queries_file);
      if (!qrdr.open()) {
        usage("Cannot open: " + queries_file);
        return EXIT_FAILURE; 
      }
      while (qrdr.loadIntegers(tmp)) {
        queries.push_back(tmp);
      }
    }
              
    try { 
      demo_data(data, queries, threshold);
    } catch (const std::exception& e) {
      std::cerr << "Exception: " << e.what() << std::endl;
      return EXIT_FAILURE;
    }
  } else {
    try {
      // Previous demo with threshold 3
      //demo_random(20000000, 50000, 100, 3);
      for (unsigned k = 1; k < 10; ++k) {
        std::cout << "Demo threshold:" << k << std::endl;
        demo_random(20000000, 50000, 100, k);
        std::cout << "=======================" << std::endl;
      }
    } catch (const std::exception& e) {
      std::cerr << "Exception: " << e.what() << std::endl;
      return EXIT_FAILURE;
    }
  }
  return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x1, -0x8(%rbp)
je 0x750e
cmpl $0x7, -0x8(%rbp)
je 0x6d30
leaq -0x31(%rbp), %rdi
movq %rdi, -0x228(%rbp)
callq 0x3480
movq -0x228(%rbp), %rdx
leaq 0xd3df(%rip), %rsi      # 0x140aa
leaq -0x30(%rbp), %rdi
callq 0x8660
jmp 0x6cd6
leaq -0x30(%rbp), %rdi
callq 0x6c20
jmp 0x6ce1
leaq -0x30(%rbp), %rdi
callq 0x31b0
leaq -0x31(%rbp), %rdi
callq 0x32e0
movl $0x1, -0x4(%rbp)
jmp 0x7693
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6d22
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x31b0
leaq -0x31(%rbp), %rdi
callq 0x32e0
jmp 0x769f
leaq -0x68(%rbp), %rdi
callq 0x3360
leaq -0x88(%rbp), %rdi
callq 0x3360
movl $0xffffffff, -0x8c(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x90(%rbp)
movl -0x90(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x7042
movq -0x10(%rbp), %rax
movslq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x238(%rbp)
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x230(%rbp)
callq 0x3480
movq -0x238(%rbp), %rsi
movq -0x230(%rbp), %rdx
leaq -0xb0(%rbp), %rdi
callq 0x8660
jmp 0x6dad
leaq 0xd3ad(%rip), %rsi      # 0x14161
leaq -0xb0(%rbp), %rdi
callq 0x8a60
movb %al, -0x239(%rbp)
jmp 0x6dc8
leaq -0xb0(%rbp), %rdi
callq 0x31b0
leaq -0xb1(%rbp), %rdi
callq 0x32e0
movb -0x239(%rbp), %al
testb $0x1, %al
jne 0x6dec
jmp 0x6e5e
movq -0x10(%rbp), %rax
movslq -0x90(%rbp), %rcx
movl %ecx, %edx
incl %edx
movl %edx, -0x90(%rbp)
movq 0x8(%rax,%rcx,8), %rsi
leaq -0x68(%rbp), %rdi
callq 0x3350
jmp 0x6e11
jmp 0x702c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6e3c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x31b0
leaq -0xb1(%rbp), %rdi
callq 0x32e0
jmp 0x74f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x74f4
movq -0x10(%rbp), %rax
movslq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x250(%rbp)
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x248(%rbp)
callq 0x3480
movq -0x250(%rbp), %rsi
movq -0x248(%rbp), %rdx
leaq -0xd8(%rbp), %rdi
callq 0x8660
jmp 0x6ea3
leaq 0xd2c2(%rip), %rsi      # 0x1416c
leaq -0xd8(%rbp), %rdi
callq 0x8a60
movb %al, -0x251(%rbp)
jmp 0x6ebe
leaq -0xd8(%rbp), %rdi
callq 0x31b0
leaq -0xd9(%rbp), %rdi
callq 0x32e0
movb -0x251(%rbp), %al
testb $0x1, %al
jne 0x6ee2
jmp 0x6f46
movq -0x10(%rbp), %rax
movslq -0x90(%rbp), %rcx
movl %ecx, %edx
incl %edx
movl %edx, -0x90(%rbp)
movq 0x8(%rax,%rcx,8), %rsi
leaq -0x88(%rbp), %rdi
callq 0x3350
jmp 0x6f0a
jmp 0x702a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x6f35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x31b0
leaq -0xd9(%rbp), %rdi
callq 0x32e0
jmp 0x74f4
movq -0x10(%rbp), %rax
movslq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x268(%rbp)
leaq -0x101(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0x3480
movq -0x268(%rbp), %rsi
movq -0x260(%rbp), %rdx
leaq -0x100(%rbp), %rdi
callq 0x8660
jmp 0x6f8b
leaq 0xd1e4(%rip), %rsi      # 0x14176
leaq -0x100(%rbp), %rdi
callq 0x8a60
movb %al, -0x269(%rbp)
jmp 0x6fa6
leaq -0x100(%rbp), %rdi
callq 0x31b0
leaq -0x101(%rbp), %rdi
callq 0x32e0
movb -0x269(%rbp), %al
testb $0x1, %al
jne 0x6fca
jmp 0x7028
movq -0x10(%rbp), %rax
movl -0x90(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x90(%rbp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
callq 0x33d0
movl %eax, -0x8c(%rbp)
jmp 0x7028
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x7017
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x31b0
leaq -0x101(%rbp), %rdi
callq 0x32e0
jmp 0x74f4
jmp 0x702a
jmp 0x702c
jmp 0x702e
movl -0x90(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x90(%rbp)
jmp 0x6d59
leaq -0x68(%rbp), %rdi
callq 0x3440
testb $0x1, %al
jne 0x706c
leaq -0x88(%rbp), %rdi
callq 0x3440
testb $0x1, %al
jne 0x706c
cmpl $0x0, -0x8c(%rbp)
jge 0x710e
leaq -0x129(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x3480
movq -0x278(%rbp), %rdx
leaq 0xd0f5(%rip), %rsi      # 0x14182
leaq -0x128(%rbp), %rdi
callq 0x8660
jmp 0x709b
leaq -0x128(%rbp), %rdi
callq 0x6c20
jmp 0x70a9
leaq -0x128(%rbp), %rdi
callq 0x31b0
leaq -0x129(%rbp), %rdi
callq 0x32e0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x130(%rbp)
jmp 0x74a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x70fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x128(%rbp), %rdi
callq 0x31b0
leaq -0x129(%rbp), %rdi
callq 0x32e0
jmp 0x74f4
leaq -0x148(%rbp), %rdi
callq 0x7ff0
leaq -0x160(%rbp), %rdi
callq 0x84f0
leaq -0x188(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x8a90
jmp 0x7138
leaq -0x188(%rbp), %rdi
callq 0x8ad0
movb %al, -0x279(%rbp)
jmp 0x714c
movb -0x279(%rbp), %al
testb $0x1, %al
jne 0x71e4
jmp 0x715c
leaq 0xd04d(%rip), %rsi      # 0x141b0
leaq -0x1a8(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x8b40
jmp 0x7175
leaq -0x1a8(%rbp), %rdi
callq 0x6c20
jmp 0x7183
leaq -0x1a8(%rbp), %rdi
callq 0x31b0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x130(%rbp)
jmp 0x722e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x74dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x72db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x1a8(%rbp), %rdi
callq 0x31b0
jmp 0x72db
jmp 0x71e6
leaq -0x188(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x8c50
movb %al, -0x27a(%rbp)
jmp 0x7201
movb -0x27a(%rbp), %al
testb $0x1, %al
jne 0x720d
jmp 0x7224
leaq -0x160(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x8e90
jmp 0x7222
jmp 0x71e6
movl $0x0, -0x130(%rbp)
leaq -0x188(%rbp), %rdi
callq 0x8f00
movl -0x130(%rbp), %eax
testl %eax, %eax
jne 0x748d
jmp 0x724a
leaq -0x1c0(%rbp), %rdi
callq 0x84f0
leaq -0x1e8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x8a90
jmp 0x726b
leaq -0x1e8(%rbp), %rdi
callq 0x8ad0
movb %al, -0x27b(%rbp)
jmp 0x727f
movb -0x27b(%rbp), %al
testb $0x1, %al
jne 0x732b
jmp 0x728f
leaq 0xcf1a(%rip), %rsi      # 0x141b0
leaq -0x208(%rbp), %rdi
leaq -0x88(%rbp), %rdx
callq 0x8b40
jmp 0x72ab
leaq -0x208(%rbp), %rdi
callq 0x6c20
jmp 0x72b9
leaq -0x208(%rbp), %rdi
callq 0x31b0
movl $0x1, -0x4(%rbp)
movl $0x1, -0x130(%rbp)
jmp 0x7375
leaq -0x188(%rbp), %rdi
callq 0x8f00
jmp 0x74dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x74d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x73b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x31b0
jmp 0x73b2
jmp 0x732d
leaq -0x1e8(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x8c50
movb %al, -0x27c(%rbp)
jmp 0x7348
movb -0x27c(%rbp), %al
testb $0x1, %al
jne 0x7354
jmp 0x736b
leaq -0x1c0(%rbp), %rdi
leaq -0x148(%rbp), %rsi
callq 0x8e90
jmp 0x7369
jmp 0x732d
movl $0x0, -0x130(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x8f00
movl -0x130(%rbp), %eax
testl %eax, %eax
jne 0x7481
jmp 0x7391
movslq -0x8c(%rbp), %rdx
leaq -0x160(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x4250
jmp 0x73ad
jmp 0x7477
leaq -0x1e8(%rbp), %rdi
callq 0x8f00
jmp 0x74d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x74d0
movq -0x40(%rbp), %rdi
callq 0x3110
movq %rax, -0x210(%rbp)
movq 0x16bf2(%rip), %rdi     # 0x1dfe8
leaq 0xcdc1(%rip), %rsi      # 0x141be
callq 0x3280
movq %rax, -0x288(%rbp)
jmp 0x740b
movq -0x210(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq -0x288(%rbp), %rdi
movq %rax, %rsi
callq 0x3280
movq %rax, -0x290(%rbp)
jmp 0x7433
movq -0x290(%rbp), %rdi
movq 0x16b67(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x7448
movl $0x1, -0x4(%rbp)
movl $0x1, -0x130(%rbp)
callq 0x3430
jmp 0x7473
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
callq 0x3430
jmp 0x7475
jmp 0x7481
jmp 0x74d0
movl $0x0, -0x130(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x8770
leaq -0x160(%rbp), %rdi
callq 0x8770
leaq -0x148(%rbp), %rdi
callq 0x8800
leaq -0x88(%rbp), %rdi
callq 0x31b0
leaq -0x68(%rbp), %rdi
callq 0x31b0
movl -0x130(%rbp), %eax
testl %eax, %eax
je 0x74cb
jmp 0x74c6
jmp 0x7693
jmp 0x768c
leaq -0x1c0(%rbp), %rdi
callq 0x8770
leaq -0x160(%rbp), %rdi
callq 0x8770
leaq -0x148(%rbp), %rdi
callq 0x8800
leaq -0x88(%rbp), %rdi
callq 0x31b0
leaq -0x68(%rbp), %rdi
callq 0x31b0
jmp 0x769f
movl $0x1, -0x214(%rbp)
cmpl $0xa, -0x214(%rbp)
jae 0x7673
movq 0x16a9c(%rip), %rdi     # 0x1dfc8
leaq 0xcc97(%rip), %rsi      # 0x141ca
callq 0x3280
movq %rax, -0x298(%rbp)
jmp 0x7541
movq -0x298(%rbp), %rdi
movl -0x214(%rbp), %esi
callq 0x3340
movq %rax, -0x2a0(%rbp)
jmp 0x755c
movq -0x2a0(%rbp), %rdi
movq 0x16a3e(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x7571
movl -0x214(%rbp), %eax
movl %eax, %ecx
movl $0x1312d00, %edi        # imm = 0x1312D00
movl $0xc350, %esi           # imm = 0xC350
movl $0x64, %edx
callq 0x5790
jmp 0x758f
movq 0x16a32(%rip), %rdi     # 0x1dfc8
leaq 0xcc3d(%rip), %rsi      # 0x141da
callq 0x3280
movq %rax, -0x2a8(%rbp)
jmp 0x75ab
movq -0x2a8(%rbp), %rdi
movq 0x169ef(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x75c0
jmp 0x75c2
movl -0x214(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x214(%rbp)
jmp 0x7518
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0x769f
movq -0x40(%rbp), %rdi
callq 0x3110
movq %rax, -0x220(%rbp)
movq 0x169df(%rip), %rdi     # 0x1dfe8
leaq 0xcbae(%rip), %rsi      # 0x141be
callq 0x3280
movq %rax, -0x2b0(%rbp)
jmp 0x761e
movq -0x220(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq -0x2b0(%rbp), %rdi
movq %rax, %rsi
callq 0x3280
movq %rax, -0x2b8(%rbp)
jmp 0x7646
movq -0x2b8(%rbp), %rdi
movq 0x16954(%rip), %rsi     # 0x1dfa8
callq 0x32c0
jmp 0x765b
movl $0x1, -0x4(%rbp)
movl $0x1, -0x130(%rbp)
callq 0x3430
jmp 0x7693
jmp 0x768a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
callq 0x3430
jmp 0x7688
jmp 0x769f
jmp 0x768c
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x3470
movq %rax, %rdi
callq 0x8f40