// File: /workspace/github_cpp_makefile_star2_O1/lemire[P]fastscancount/include/fastscancount.h
// Function: fastscancount::fastscancount(std::vector<std::vector<unsigned int, std::allocator<unsigned int>> const*, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>> const*>> const&, std::vector<unsigned int, std::allocator<unsigned int>>&, unsigned char)
void fastscancount(const std::vector<const std::vector<uint32_t>*> &data,
                   std::vector<uint32_t> &out, uint8_t threshold) {
  size_t cache_size = 65536;
  size_t range = cache_size;
  std::vector<uint8_t> counters(cache_size);
  size_t ds = data.size();
  out.resize( 4 * range); // let us add lots of capacity
  uint32_t *output = out.data();
  uint32_t *initout = out.data();
  std::vector<size_t> iters(ds);
  size_t countsofar = 0;
  uint32_t largest = 0;
  for (size_t c = 0; c < ds; c++) {
    if (largest < (*data[c])[data[c]->size() - 1])
      largest = (*data[c])[data[c]->size() - 1];
  }
  // we are assuming that all vectors in data are non-empty
  for (size_t start = 0; start < largest; start += range) {
    // make sure that the capacity is sufficient
    countsofar = output - initout;
    if (out.size() - countsofar < range) {
      out.resize(out.size() + 4 * range);
      initout = out.data();
      output = out.data() + countsofar;
    }
    memset(counters.data(), 0, range);
    for (size_t c = 0; c < ds; c++) {
      size_t it = iters[c]; // recover where we were
      const std::vector<uint32_t> &d = *data[c];
      const size_t itend = d.size();
      if (it == itend) // check that there is data to be processed
        continue;      // exhausted
      // check if we need to be careful:
      bool near_the_end = (d[itend - 1] < start + range);
      if (near_the_end) {
        output = natefastscancount_finalcheck(counters.data(), it, d.data(),
                                              start, itend, threshold, output);
      } else {
        output = natefastscancount_maincheck(counters.data(), it, d.data(),
                                             start, range, threshold, output);
      }
      iters[c] = it; // store it for next round
    }
  }
  countsofar = output - initout;
  out.resize(countsofar);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movl $0x10000, %edi          # imm = 0x10000
callq 0x2220
movq %rax, 0x18(%rsp)
movl $0x10000, %edx          # imm = 0x10000
movq %rax, %rdi
xorl %esi, %esi
callq 0x2150
movq (%rbx), %r15
movq %rbx, 0x20(%rsp)
movq 0x8(%rbx), %rbx
movl $0x40000, %esi          # imm = 0x40000
movq %r14, %rdi
callq 0x58f0
movq %rbx, %r12
subq %r15, %r12
sarq $0x3, %r12
movq (%r14), %r13
leaq 0x40(%rsp), %rdi
leaq 0xf(%rsp), %rdx
movq %r12, %rsi
callq 0x5922
movq %rbx, 0x38(%rsp)
cmpq %r15, %rbx
je 0x2625
movq 0x20(%rsp), %rax
movq (%rax), %rax
cmpq $0x1, %r12
movq %r12, %rcx
adcq $0x0, %rcx
xorl %edx, %edx
xorl %edi, %edi
movq (%rax,%rdx,8), %rsi
movq 0x8(%rsi), %rsi
movl -0x4(%rsi), %esi
cmpl %esi, %edi
cmoval %edi, %esi
incq %rdx
movl %esi, %edi
cmpq %rdx, %rcx
jne 0x2609
jmp 0x2627
xorl %esi, %esi
testl %esi, %esi
je 0x2771
movq %r15, 0x30(%rsp)
movl %esi, %eax
movq %rax, 0x28(%rsp)
cmpq $0x1, %r12
adcq $0x0, %r12
xorl %r15d, %r15d
movq %r13, 0x10(%rsp)
movq %r13, %rbx
subq 0x10(%rsp), %rbx
movq %rbx, %rax
sarq $0x2, %rax
movq 0x8(%r14), %rsi
subq (%r14), %rsi
sarq $0x2, %rsi
movq %rsi, %rcx
subq %rax, %rcx
cmpq $0xffff, %rcx           # imm = 0xFFFF
ja 0x2691
addq $0x40000, %rsi          # imm = 0x40000
movq %r14, %rdi
callq 0x58f0
movq (%r14), %rax
movq %rax, 0x10(%rsp)
addq %rax, %rbx
movq %rbx, %r13
movl $0x10000, %edx          # imm = 0x10000
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2150
movq 0x38(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x275d
movq 0x40(%rsp), %rax
movq 0x20(%rsp), %rcx
movq (%rcx), %rcx
leaq 0x10000(%r15), %rdx
movq %rbx, %rsi
subq %r15, %rsi
xorl %edi, %edi
movq (%rax,%rdi,8), %r8
movq (%rcx,%rdi,8), %r10
movq (%r10), %r9
movq 0x8(%r10), %r11
subq %r9, %r11
movq %r11, %r10
sarq $0x2, %r10
cmpq %r10, %r8
je 0x2728
movl -0x4(%r9,%r11), %r11d
cmpq %r11, %rdx
jbe 0x2732
cmpq %r10, %r8
jae 0x2724
movl (%r9,%r8,4), %r11d
movb (%rsi,%r11), %bl
cmpb %bpl, %bl
jne 0x2713
movl %r11d, (%r13)
addq $0x4, %r13
incb %bl
movb %bl, (%rsi,%r11)
incq %r8
cmpq %r8, %r10
jne 0x26fe
movq %r10, %r8
movq %r8, (%rax,%rdi,8)
incq %rdi
cmpq %r12, %rdi
jne 0x26d1
jmp 0x275d
movl (%r9,%r8,4), %r10d
cmpq %r10, %rdx
jbe 0x2724
movb (%rsi,%r10), %r11b
cmpb %bpl, %r11b
jne 0x274c
movl %r10d, (%r13)
addq $0x4, %r13
incb %r11b
movb %r11b, (%rsi,%r10)
movl 0x4(%r9,%r8,4), %r10d
incq %r8
jmp 0x2736
addq $0x10000, %r15          # imm = 0x10000
cmpq 0x28(%rsp), %r15
jb 0x264b
jmp 0x2776
movq %r13, 0x10(%rsp)
subq 0x10(%rsp), %r13
sarq $0x2, %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x58f0
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
movq 0x18(%rsp), %rbx
je 0x27a6
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2230
movl $0x10000, %esi          # imm = 0x10000
movq %rbx, %rdi
callq 0x2230
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x27cb
jmp 0x27c6
movq %rax, %r14
jmp 0x27e5
movq %rax, %r14
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x27e5
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x2230
movl $0x10000, %esi          # imm = 0x10000
movq 0x18(%rsp), %rdi
callq 0x2230
movq %r14, %rdi
callq 0x2390