Skip to content
Snippets Groups Projects
Select Git revision
  • 5033e1311d10b1bb06452111e01d232d5fedd78e
  • devel default
  • master
  • fo
  • jirka/typing
  • fo-base
  • mj/submit-images
  • jk/issue-96
  • jk/issue-196
  • honza/add-contestant
  • honza/mr7
  • honza/mrf
  • honza/mrd
  • honza/mra
  • honza/mr6
  • honza/submit-images
  • honza/kolo-vs-soutez
  • jh-stress-test-wip
  • shorten-schools
19 results

util.py

Blame
  • hash_functions.h 2.61 KiB
    #include <cstdlib>
    #include <string>
    
    #include "random.h"
    
    using namespace std;
    
    // If the condition is not true, report an error and halt.
    #define EXPECT(condition, message) do { if (!(condition)) expect_failed(message); } while (0)
    
    void expect_failed(const string& message);
    
    class TabulationHash {
        /*
         * Hash function for hashing by tabulation.
         *
         * The 32-bit key is split to four 8-bit parts. Each part indexes
         * a separate table of 256 randomly generated values. Obtained values
         * are XORed together.
         */
    
        size_t num_buckets;
        RandomGen &random_gen;
        uint32_t tables[4][256];
    
    public:
        TabulationHash(size_t num_buckets, RandomGen &random_gen) : num_buckets(num_buckets), random_gen(random_gen) {
            regenerate();
        }
    
        void regenerate() {
            for (int i=0; i<4; i++)
                for (int j=0; j<256; j++)
                    tables[i][j] = random_gen.next_u32();
        }
    
        uint32_t hash(uint32_t key) const {
            uint32_t h0 = key & 0xff;
            uint32_t h1 = (key >> 8) & 0xff;
            uint32_t h2 = (key >> 16) & 0xff;
            uint32_t h3 = (key >> 24) & 0xff;
            return (tables[0][h0] ^ tables[1][h1] ^ tables[2][h2] ^ tables[3][h3]) % num_buckets;
        }
    };
    
    class FixedHash {
    public:
        static constexpr uint32_t keys = 5, max_regenerations = 6, table_size = 16;
    
    private:
        static constexpr uint32_t hashes[max_regenerations][2][keys] {
            { // Two items hashed into the same bucket by both functions
                { 1, 7, 3, 7, 10 },
                { 2, 7, 4, 7, 11 }
            },
            { // Three items stored in two positions
                { 1, 7, 3, 8, 7 },
                { 2, 8, 4, 7, 8 }
            },
            { // Four items stored in three positions
                { 1, 7, 7, 8, 9 },
                { 2, 8, 9, 7, 8 }
            },
            { // Five should be possible to store in five positions, but the cuckoo's insert operation may not find the proper locations
                { 1, 2, 3, 4, 5 },
                { 2, 3, 4, 5, 1 }
            },
            { // Five should be possible to store in six positions, the timeout in the insert may not be sufficient
                { 1, 2, 3, 4, 5 },
                { 2, 3, 4, 5, 6 }
            },
            { // This should be easy
                { 8, 7, 7, 8, 12 },
                { 11, 6, 7, 9, 0 }
            }
        };
    
        size_t regenerations, id;
    
    public:
        FixedHash(size_t id) : regenerations{0}, id{id} {}
    
        uint32_t hash(uint32_t key) const {
            EXPECT(key < keys, "Invalid key");
            return hashes[regenerations][id][key];
        }
    
        void regenerate() {
            regenerations++;
            EXPECT(regenerations < max_regenerations, "Too many rehashes");
        }
    };