// File: /workspace/github_cpp_makefile_star2_O1/ralgond[P]SortedListIntersection/./bloom_filter.hpp
// Function: bloom_parameters::compute_optimal_parameters()
virtual bool compute_optimal_parameters()
   {
      /*
        Note:
        The following will attempt to find the number of hash functions
        and minimum amount of storage bits required to construct a bloom
        filter consistent with the user defined false positive probability
        and estimated element insertion count.
      */

      if (!(*this))
         return false;

      double min_m  = std::numeric_limits<double>::infinity();
      double min_k  = 0.0;
      double k      = 1.0;

      while (k < 1000.0)
      {
         const double numerator   = (- k * projected_element_count);
         const double denominator = std::log(1.0 - std::pow(false_positive_probability, 1.0 / k));

         const double curr_m = numerator / denominator;

         if (curr_m < min_m)
         {
            min_m = curr_m;
            min_k = k;
         }

         k += 1.0;
      }

      optimal_parameters_t& optp = optimal_parameters;

      optp.number_of_hashes = static_cast<unsigned int>(min_k);

      optp.table_size = static_cast<unsigned long long int>(min_m);

      optp.table_size += (((optp.table_size % bits_per_char) != 0) ? (bits_per_char - (optp.table_size % bits_per_char)) : 0);

      if (optp.number_of_hashes < minimum_number_of_hashes)
         optp.number_of_hashes = minimum_number_of_hashes;
      else if (optp.number_of_hashes > maximum_number_of_hashes)
         optp.number_of_hashes = maximum_number_of_hashes;

      if (optp.table_size < minimum_size)
         optp.table_size = minimum_size;
      else if (optp.table_size > maximum_size)
         optp.table_size = maximum_size;

      return true;
   }

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x30, %rsp
movq %rdi, %rbx
movq 0x8(%rdi), %rax
movb $0x1, %bpl
cmpq 0x10(%rdi), %rax
jbe 0x3278
testb %bpl, %bpl
jne 0x3269
vmovsd 0x2f9d(%rip), %xmm0     # 0x6108
vxorpd %xmm2, %xmm2, %xmm2
vmovsd 0x2f99(%rip), %xmm1     # 0x6110
movl $0x3e7, %r14d           # imm = 0x3E7
vmovapd %xmm0, (%rsp)
vmovapd %xmm2, 0x20(%rsp)
vmovsd %xmm1, 0x18(%rsp)
vmovapd (%rsp), %xmm0
vxorpd 0x2f7b(%rip){1to2}, %xmm0, %xmm0 # 0x6118
vcvtusi2sdq 0x20(%rbx), %xmm4, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x10(%rsp)
vmovsd 0x28(%rbx), %xmm0
vmovsd 0x2f4d(%rip), %xmm1     # 0x6108
vdivsd (%rsp), %xmm1, %xmm1
callq 0x21f0
vmovsd 0x2f3b(%rip), %xmm1     # 0x6108
vsubsd %xmm0, %xmm1, %xmm0
callq 0x2100
vmovapd 0x20(%rsp), %xmm2
vmovsd 0x18(%rsp), %xmm1
vmovsd 0x10(%rsp), %xmm3
vdivsd %xmm0, %xmm3, %xmm0
vcmpltsd %xmm1, %xmm0, %k1
vmovapd (%rsp), %xmm3
vmovsd %xmm3, %xmm2, %xmm2 {%k1}
vminsd %xmm1, %xmm0, %xmm1
vmovapd (%rsp), %xmm0
vaddsd 0x2ef9(%rip), %xmm0, %xmm0 # 0x6108
decl %r14d
jne 0x317d
vcvttsd2usi %xmm2, %ecx
movl %ecx, 0x38(%rbx)
vcvttsd2usi %xmm1, %rdx
movl %edx, %esi
andl $0x7, %esi
movl $0x8, %eax
subq %rsi, %rax
testq %rsi, %rsi
cmoveq %rsi, %rax
addq %rdx, %rax
movq %rax, 0x40(%rbx)
movl 0x18(%rbx), %edx
cmpl %ecx, %edx
ja 0x3250
movl 0x1c(%rbx), %edx
cmpl %ecx, %edx
jae 0x3253
movl %edx, 0x38(%rbx)
movq 0x8(%rbx), %rcx
cmpq %rcx, %rax
jb 0x3265
movq 0x10(%rbx), %rcx
cmpq %rcx, %rax
jbe 0x3269
movq %rcx, 0x40(%rbx)
xorb $0x1, %bpl
movl %ebp, %eax
addq $0x30, %rsp
popq %rbx
popq %r14
popq %rbp
retq
movl 0x18(%rbx), %eax
decl %eax
cmpl 0x1c(%rbx), %eax
jae 0x315a
cmpq $0x0, 0x20(%rbx)
je 0x315a
movq 0x28(%rbx), %rax
movq %rax, %rcx
btrq $0x3f, %rcx
leaq -0x1(%rcx), %rdx
movabsq $0xfffffffffffff, %rsi  # imm = 0xFFFFFFFFFFFFF
cmpq %rsi, %rdx
setb %dl
testq %rax, %rax
sets %al
andb %al, %dl
movabsq $0x7ff0000000000000, %rsi # imm = 0x7FF0000000000000
cmpq %rsi, %rcx
sete %sil
orb %dl, %sil
movabsq $-0x10000000000000, %rdx # imm = 0xFFF0000000000000
addq %rcx, %rdx
shrq $0x35, %rdx
cmpl $0x3ff, %edx            # imm = 0x3FF
setb %cl
andb %al, %cl
orb %sil, %cl
jne 0x315a
movq 0x30(%rbx), %rax
incq %rax
cmpq $0x2, %rax
setb %bpl
jmp 0x315a