// File: /workspace/github_cpp_makefile_star2_O2/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 %rbx
subq $0x38, %rsp
movq %rdi, %rbx
callq 0x3096
movl %eax, %ebp
testb %al, %al
jne 0x2fc3
vmovsd 0x3266(%rip), %xmm1     # 0x6130
vmovsd 0x3266(%rip), %xmm3     # 0x6138
vxorpd %xmm2, %xmm2, %xmm2
vmovsd 0x3262(%rip), %xmm0     # 0x6140
vucomisd %xmm3, %xmm0
jbe 0x2f74
vxorpd 0x3256(%rip){1to2}, %xmm3, %xmm0 # 0x6148
vmovsd %xmm1, 0x8(%rsp)
vmovapd %xmm2, 0x20(%rsp)
vmovapd %xmm3, 0x10(%rsp)
vcvtusi2sdq 0x20(%rbx), %xmm5, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vmovsd 0x3221(%rip), %xmm1     # 0x6138
vmovsd %xmm0, (%rsp)
vmovsd 0x28(%rbx), %xmm0
vdivsd %xmm3, %xmm1, %xmm1
callq 0x2250
vmovsd 0x3206(%rip), %xmm1     # 0x6138
vsubsd %xmm0, %xmm1, %xmm0
callq 0x2140
vmovsd (%rsp), %xmm4
vmovsd 0x8(%rsp), %xmm1
vmovapd 0x10(%rsp), %xmm3
vmovapd 0x20(%rsp), %xmm2
vdivsd %xmm0, %xmm4, %xmm0
vcmpltsd %xmm1, %xmm0, %k1
vminsd %xmm1, %xmm0, %xmm1
vmovsd %xmm3, %xmm2, %xmm2 {%k1}
vaddsd 0x31c9(%rip), %xmm3, %xmm3 # 0x6138
jmp 0x2ed6
vcvttsd2usi %xmm2, %ecx
vcvttsd2usi %xmm1, %rdx
movl %edx, %esi
movl %ecx, 0x38(%rbx)
andl $0x7, %esi
pushq $0x8
popq %rax
subq %rsi, %rax
testq %rsi, %rsi
cmoveq %rsi, %rax
addq %rdx, %rax
movq %rax, 0x40(%rbx)
movl 0x18(%rbx), %edx
cmpl %ecx, %edx
ja 0x2faa
movl 0x1c(%rbx), %edx
cmpl %ecx, %edx
jae 0x2fad
movl %edx, 0x38(%rbx)
movq 0x8(%rbx), %rcx
cmpq %rcx, %rax
jb 0x2fbf
movq 0x10(%rbx), %rcx
cmpq %rcx, %rax
jbe 0x2fc3
movq %rcx, 0x40(%rbx)
xorb $0x1, %bpl
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %rbp
retq