Advertisement
stgatilov

Symmetric difference merge: generator

Jul 23rd, 2017
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.69 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <algorithm>
  6. #include <vector>
  7.  
  8. //======================== Perfect hash generator =========================
  9.  
  10. typedef uint32_t hash_int;
  11.  
  12. //searching for a hash function of this kind:
  13. hash_int HashFunction(hash_int param, hash_int x, int bits) {
  14.     return (param * x) >> hash_int(32 - bits);
  15. }
  16.  
  17. static const hash_int NO_PARAM = hash_int(-1);
  18. hash_int GeneratePerfectHash(std::vector<hash_int> values, int bits, hash_int tries = NO_PARAM) {
  19.     std::vector<int> table;
  20.     for (hash_int param = 0; param < tries; param++) {
  21.         table.assign(hash_int(1)<<bits, 0);
  22.         bool ok = true;
  23.         for (int i = 0; ok && i < values.size(); i++) {
  24.             hash_int x = values[i];
  25.             hash_int cell = HashFunction(param, x, bits);
  26.             if (table[cell]++)
  27.                 ok = false;
  28.         }
  29.         if (ok)
  30.             return param;
  31.     }
  32.     return NO_PARAM;
  33. }
  34.  
  35. //======================== Lookup table generator =========================
  36.  
  37. template<class T> void PrintTable(const T *lut, int size) {
  38.     for (int i = 0; i < size; i++) {
  39.         const unsigned char *entry = (unsigned char*) &lut[i];
  40.         printf("\t{");
  41.         for (int j = 0; j < sizeof(T); j++) {
  42.             if (j) printf(", ");
  43.             printf("0x%02X", (unsigned int)(entry[j]));
  44.         }
  45.         printf("},\n");
  46.     }
  47.     printf("\n");
  48. }
  49.  
  50. struct m128b {
  51.     char d[16];
  52. };
  53. struct m256d {
  54.     int d[8];
  55. };
  56.  
  57. static const int HASH_BITS = 7;
  58. m256d lookup_perm[1<<HASH_BITS];
  59. uint8_t lookup_di[1<<HASH_BITS];
  60.  
  61. uint32_t GenerateLookupTableHash() {
  62.     std::vector<uint32_t> allMasks;
  63.     std::vector<m256d> allPerms;
  64.     std::vector<uint8_t> allDi;
  65.     for (int m = 0; m < 1<<8; m++) {
  66.         int ak = 0;
  67.         int a[8], b[8];
  68.         m256d perm;
  69.         for (int i = 0; i < 8; i++) {
  70.             if (m & (1<<i)) {
  71.                 perm.d[i] = ak;
  72.                 a[ak++] = i;
  73.             }
  74.             else {
  75.                 perm.d[i] = 4 + (i-ak);
  76.                 b[i-ak] = i;
  77.             }
  78.         }
  79.         if (ak != 4) continue;
  80.        
  81.         int mask = 0;
  82.         for (int s = 0; s < 4; s++)
  83.             for (int i = 0; i < 4; i++) {
  84.                 int bit = (a[i] < b[(i+s) % 4]);
  85.                 mask ^= (bit << (s*4+i));
  86.             }
  87.  
  88.         int di = 0;
  89.         for (int i = 0; i < 4; i++) di += (m >> i) & 1;
  90.  
  91.         allMasks.push_back(mask);
  92.         allPerms.push_back(perm);
  93.         allDi.push_back(di);
  94.     }
  95.  
  96.     uint32_t param = GeneratePerfectHash(allMasks, HASH_BITS);
  97.     assert(param != NO_PARAM);
  98.  
  99.     memset(lookup_perm, -1, sizeof(lookup_perm));
  100.     memset(lookup_di, -1, sizeof(lookup_di));
  101.     for (int i = 0; i < allMasks.size(); i++) {
  102.         uint32_t hash = HashFunction(param, allMasks[i], HASH_BITS);
  103.         lookup_perm[hash] = allPerms[i];
  104.         lookup_di[hash] = allDi[i];
  105.     }
  106.     return param;
  107. }
  108.  
  109. m128b lookup_compress[16];
  110. void InitCompactionLut() {
  111.     for (int m = 0; m < 16; m++) {
  112.         m128b res;
  113.         memset(res.d, -1, sizeof(res));
  114.         int k = 0;
  115.         for (int i = 0; i < 4; i++)
  116.             if (m & (1<<i)) {
  117.                 for (int t = 0; t < 4; t++)
  118.                     res.d[k++] = 4 * i + t;
  119.             }
  120.         lookup_compress[m] = res;
  121.     }
  122. }
  123.  
  124. void GenAll() {
  125.     InitCompactionLut();
  126.     PrintTable(lookup_compress, 16);
  127.  
  128.     uint32_t param = GenerateLookupTableHash();
  129.     printf("lookup_perm (%08X):\n", param);
  130.     PrintTable(lookup_perm, 1 << HASH_BITS);
  131.     printf("lookup_di (%08X):\n", param);
  132.     PrintTable(lookup_di, 1 << HASH_BITS);
  133. }
  134.  
  135. int main() {
  136.     GenAll();
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement