// File: 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:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq 0x48(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x58f0
testb $0x1, %al
jne 0x551e
jmp 0x5528
movb $0x0, 0x57(%rsp)
jmp 0x5728
callq 0x59f0
vmovsd %xmm0, 0x40(%rsp)
vpxor %xmm0, %xmm0, %xmm0
vmovsd %xmm0, 0x38(%rsp)
vmovsd 0x8bdb(%rip), %xmm0     # 0xe120
vmovsd %xmm0, 0x30(%rsp)
vmovsd 0x8bd5(%rip), %xmm0     # 0xe128
vucomisd 0x30(%rsp), %xmm0
jbe 0x561a
movq 0x8(%rsp), %rax
vmovsd 0x30(%rsp), %xmm0
vmovq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
vmovq %rcx, %xmm0
vcvtusi2sdq 0x20(%rax), %xmm1, %xmm1
vmulsd %xmm1, %xmm0, %xmm0
vmovsd %xmm0, 0x28(%rsp)
vmovsd 0x28(%rax), %xmm0
vmovsd 0x8b81(%rip), %xmm1     # 0xe120
vdivsd 0x30(%rsp), %xmm1, %xmm1
callq 0x2320
vmovaps %xmm0, %xmm1
vmovsd 0x8b6a(%rip), %xmm0     # 0xe120
vsubsd %xmm1, %xmm0, %xmm0
callq 0x2180
vmovsd %xmm0, 0x20(%rsp)
vmovsd 0x28(%rsp), %xmm0
vdivsd 0x20(%rsp), %xmm0, %xmm0
vmovsd %xmm0, 0x18(%rsp)
vmovsd 0x18(%rsp), %xmm1
vmovsd 0x40(%rsp), %xmm0
vucomisd %xmm1, %xmm0
jbe 0x5601
vmovsd 0x18(%rsp), %xmm0
vmovsd %xmm0, 0x40(%rsp)
vmovsd 0x30(%rsp), %xmm0
vmovsd %xmm0, 0x38(%rsp)
vmovsd 0x8b17(%rip), %xmm0     # 0xe120
vaddsd 0x30(%rsp), %xmm0, %xmm0
vmovsd %xmm0, 0x30(%rsp)
jmp 0x554b
movq 0x8(%rsp), %rax
addq $0x38, %rax
movq %rax, 0x10(%rsp)
vcvttsd2usi 0x38(%rsp), %ecx
movq 0x10(%rsp), %rax
movl %ecx, (%rax)
vcvttsd2usi 0x40(%rsp), %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
andq $0x7, %rax
cmpq $0x0, %rax
je 0x5676
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rcx
andq $0x7, %rcx
movl $0x8, %eax
subq %rcx, %rax
movq %rax, (%rsp)
jmp 0x567e
xorl %eax, %eax
movq %rax, (%rsp)
jmp 0x567e
movq 0x8(%rsp), %rcx
movq (%rsp), %rdx
movq 0x10(%rsp), %rax
addq 0x8(%rax), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rsp), %rax
movl (%rax), %eax
cmpl 0x18(%rcx), %eax
jae 0x56b1
movq 0x8(%rsp), %rax
movl 0x18(%rax), %ecx
movq 0x10(%rsp), %rax
movl %ecx, (%rax)
jmp 0x56d3
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movl (%rax), %eax
cmpl 0x1c(%rcx), %eax
jbe 0x56d1
movq 0x8(%rsp), %rax
movl 0x1c(%rax), %ecx
movq 0x10(%rsp), %rax
movl %ecx, (%rax)
jmp 0x56d3
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x8(%rcx), %rax
jae 0x56fb
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x8(%rax)
jmp 0x5723
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x10(%rcx), %rax
jbe 0x5721
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x8(%rax)
jmp 0x5723
movb $0x1, 0x57(%rsp)
movb 0x57(%rsp), %al
andb $0x1, %al
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)