// File: ralgond[P]SortedListIntersection/./bloom_filter.hpp
// Function: bloom_filter::generate_unique_salt()
void generate_unique_salt()
   {
      /*
        Note:
        A distinct hash function need not be implementation-wise
        distinct. In the current implementation "seeding" a common
        hash function with different values seems to be adequate.
      */
      const unsigned int predef_salt_count = 128;

      static const bloom_type predef_salt[predef_salt_count] =
                                 {
                                    0xAAAAAAAA, 0x55555555, 0x33333333, 0xCCCCCCCC,
                                    0x66666666, 0x99999999, 0xB5B5B5B5, 0x4B4B4B4B,
                                    0xAA55AA55, 0x55335533, 0x33CC33CC, 0xCC66CC66,
                                    0x66996699, 0x99B599B5, 0xB54BB54B, 0x4BAA4BAA,
                                    0xAA33AA33, 0x55CC55CC, 0x33663366, 0xCC99CC99,
                                    0x66B566B5, 0x994B994B, 0xB5AAB5AA, 0xAAAAAA33,
                                    0x555555CC, 0x33333366, 0xCCCCCC99, 0x666666B5,
                                    0x9999994B, 0xB5B5B5AA, 0xFFFFFFFF, 0xFFFF0000,
                                    0xB823D5EB, 0xC1191CDF, 0xF623AEB3, 0xDB58499F,
                                    0xC8D42E70, 0xB173F616, 0xA91A5967, 0xDA427D63,
                                    0xB1E8A2EA, 0xF6C0D155, 0x4909FEA3, 0xA68CC6A7,
                                    0xC395E782, 0xA26057EB, 0x0CD5DA28, 0x467C5492,
                                    0xF15E6982, 0x61C6FAD3, 0x9615E352, 0x6E9E355A,
                                    0x689B563E, 0x0C9831A8, 0x6753C18B, 0xA622689B,
                                    0x8CA63C47, 0x42CC2884, 0x8E89919B, 0x6EDBD7D3,
                                    0x15B6796C, 0x1D6FDFE4, 0x63FF9092, 0xE7401432,
                                    0xEFFE9412, 0xAEAEDF79, 0x9F245A31, 0x83C136FC,
                                    0xC3DA4A8C, 0xA5112C8C, 0x5271F491, 0x9A948DAB,
                                    0xCEE59A8D, 0xB5F525AB, 0x59D13217, 0x24E7C331,
                                    0x697C2103, 0x84B0A460, 0x86156DA9, 0xAEF2AC68,
                                    0x23243DA5, 0x3F649643, 0x5FA495A8, 0x67710DF8,
                                    0x9A6C499E, 0xDCFB0227, 0x46A43433, 0x1832B07A,
                                    0xC46AFF3C, 0xB9C8FFF0, 0xC9500467, 0x34431BDF,
                                    0xB652432B, 0xE367F12B, 0x427F4C1B, 0x224C006E,
                                    0x2E7E5A89, 0x96F99AA5, 0x0BEB452A, 0x2FD87C39,
                                    0x74B2E1FB, 0x222EFD24, 0xF357F60C, 0x440FCB1E,
                                    0x8BBE030F, 0x6704DC29, 0x1144D12F, 0x948B1355,
                                    0x6D8FD7E9, 0x1C11A014, 0xADD1592F, 0xFB3C712E,
                                    0xFC77642F, 0xF9C4CE8C, 0x31312FB9, 0x08B0DD79,
                                    0x318FA6E7, 0xC040D23D, 0xC0589AA7, 0x0CA5C075,
                                    0xF874B172, 0x0CF914D5, 0x784D3280, 0x4E8CFEBC,
                                    0xC569F575, 0xCDB2A091, 0x2CC016B4, 0x5C5F4421
                                 };

      if (salt_count_ <= predef_salt_count)
      {
         std::copy(predef_salt,
                   predef_salt + salt_count_,
                   std::back_inserter(salt_));

         for (std::size_t i = 0; i < salt_.size(); ++i)
         {
            /*
               Note:
               This is done to integrate the user defined random seed,
               so as to allow for the generation of unique bloom filter
               instances.
            */
            salt_[i] = salt_[i] * salt_[(i + 3) % salt_.size()] + static_cast<bloom_type>(random_seed_);
         }
      }
      else
      {
         std::copy(predef_salt, predef_salt + predef_salt_count, std::back_inserter(salt_));

         srand(static_cast<unsigned int>(random_seed_));

         while (salt_.size() < salt_count_)
         {
            bloom_type current_salt = static_cast<bloom_type>(rand()) * static_cast<bloom_type>(rand());

            if (0 == current_salt)
               continue;

            if (salt_.end() == std::find(salt_.begin(), salt_.end(), current_salt))
            {
               salt_.push_back(current_salt);
            }
         }
      }
   }

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x30(%rsp)
movl $0x80, 0x8c(%rsp)
cmpl $0x80, 0x38(%rax)
ja 0x5b92
movq 0x30(%rsp), %rdi
movl 0x38(%rdi), %eax
movl %eax, %ecx
leaq 0x86fb(%rip), %rax      # 0xe180
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x28(%rsp)
addq $0x8, %rdi
callq 0x61b0
movq 0x28(%rsp), %rsi
movq %rax, 0x80(%rsp)
movq 0x80(%rsp), %rdx
leaq 0x86ca(%rip), %rdi      # 0xe180
callq 0x6150
movq %rax, 0x78(%rsp)
movq $0x0, 0x70(%rsp)
movq 0x30(%rsp), %rdi
movq 0x70(%rsp), %rax
movq %rax, 0x20(%rsp)
addq $0x8, %rdi
callq 0x61e0
movq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rcx, %rax
jae 0x5b8d
movq 0x30(%rsp), %rdi
addq $0x8, %rdi
movq 0x70(%rsp), %rsi
callq 0x6200
movq 0x30(%rsp), %rdi
movl (%rax), %eax
movl %eax, 0x18(%rsp)
movq %rdi, %rax
addq $0x8, %rax
movq %rax, 0x8(%rsp)
movq 0x70(%rsp), %rax
addq $0x3, %rax
movq %rax, 0x10(%rsp)
addq $0x8, %rdi
callq 0x61e0
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movq 0x10(%rsp), %rax
xorl %edx, %edx
divq %rcx
movq %rdx, %rsi
callq 0x6200
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl 0x18(%rsp), %eax
imull (%rcx), %eax
movq 0x58(%rdi), %rcx
addl %ecx, %eax
movl %eax, 0x1c(%rsp)
addq $0x8, %rdi
movq 0x70(%rsp), %rsi
callq 0x6200
movl 0x1c(%rsp), %ecx
movl %ecx, (%rax)
movq 0x70(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x70(%rsp)
jmp 0x5ac9
jmp 0x5c9d
movq 0x30(%rsp), %rdi
addq $0x8, %rdi
callq 0x61b0
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rdx
leaq 0x85cf(%rip), %rdi      # 0xe180
movq %rdi, %rsi
addq $0x200, %rsi            # imm = 0x200
callq 0x6150
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x60(%rsp)
movq 0x58(%rax), %rax
movl %eax, %edi
callq 0x21c0
movq 0x30(%rsp), %rdi
addq $0x8, %rdi
callq 0x61e0
movq 0x30(%rsp), %rcx
movl 0x38(%rcx), %ecx
cmpq %rcx, %rax
jae 0x5c9b
callq 0x2070
movl %eax, 0x4(%rsp)
callq 0x2070
movl %eax, %ecx
movl 0x4(%rsp), %eax
imull %ecx, %eax
movl %eax, 0x5c(%rsp)
xorl %eax, %eax
cmpl 0x5c(%rsp), %eax
jne 0x5c1c
jmp 0x5bd8
movq 0x30(%rsp), %rdi
addq $0x8, %rdi
callq 0x6260
movq 0x30(%rsp), %rdi
movq %rax, 0x50(%rsp)
addq $0x8, %rdi
callq 0x62f0
movq 0x30(%rsp), %rdi
movq %rax, 0x40(%rsp)
addq $0x8, %rdi
callq 0x6260
movq %rax, 0x38(%rsp)
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
leaq 0x5c(%rsp), %rdx
callq 0x6290
movq %rax, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x6220
testb $0x1, %al
jne 0x5c83
jmp 0x5c96
movq 0x30(%rsp), %rdi
addq $0x8, %rdi
leaq 0x5c(%rsp), %rsi
callq 0x6320
jmp 0x5bd8
jmp 0x5c9d
addq $0x98, %rsp
retq
nopw %cs:(%rax,%rax)
nop