diff --git a/readme.md b/readme.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..caec70495782c241a52f390b2b0c552e257ac048 100644 --- a/readme.md +++ b/readme.md @@ -0,0 +1,77 @@ +A hashtable implementation using open addressing. + +### Dependencies ### +* Google Tests (```tests/CMakeList.txt``` assumes ```/usr/src/gtest```) + +### Building ### +Create a build folder and run cmake/make. +``` +mkdir build && cd build +cmake .. +make # makes everything +make hashtable # builds only lib/libhashtable.a +``` +### Tests ### +Run ```make test``` after ```make``` or execute the ```test_*``` binaries in ```bin/```. + +### Benchmark ### +Run ```bin/benchmark```, e.g.: +``` +$ bin/benchmark 10000000 +Inserting integers from 1 to 10000000 into different hashtables. +All measurements are averages over 10 runs. + +Table: hashing by division, linear probing, alpha: 0.5, s: 2 +Time: 0.259487s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by division, linear probing, alpha: 0.5, s: 4 +Time: 0.264414s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by division, linear probing, alpha: 0.75, s: 2 +Time: 0.182584s, size: 10000000, capacity: 16777216, alpha: 0.596046 + +Table: hashing by division, quadratic probing, alpha: 0.5, s: 2 +Time: 0.261645s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by division, quadratic probing, alpha: 0.5, s: 4 +Time: 0.266709s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by division, quadratic probing, alpha: 0.75, s: 2 +Time: 0.18543s, size: 10000000, capacity: 16777216, alpha: 0.596046 + +Table: hashing by division, double hashing, alpha: 0.5, s: 2 +Time: 0.258031s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by division, double hashing, alpha: 0.5, s: 4 +Time: 0.263584s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by division, double hashing, alpha: 0.75, s: 2 +Time: 0.182143s, size: 10000000, capacity: 16777216, alpha: 0.596046 + +Table: hashing by multiplication, linear probing, alpha: 0.5, s: 2 +Time: 2.34331s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by multiplication, linear probing, alpha: 0.5, s: 4 +Time: 2.26132s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by multiplication, linear probing, alpha: 0.75, s: 2 +Time: 1.89938s, size: 10000000, capacity: 16777216, alpha: 0.596046 + +Table: hashing by multiplication, quadratic probing, alpha: 0.5, s: 2 +Time: 5.27264s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by multiplication, quadratic probing, alpha: 0.5, s: 4 +Time: 4.91861s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by multiplication, quadratic probing, alpha: 0.75, s: 2 +Time: 4.98173s, size: 10000000, capacity: 16777216, alpha: 0.596046 + +Table: hashing by multiplication, double hashing, alpha: 0.5, s: 2 +Time: 19.5598s, size: 10000000, capacity: 33554432, alpha: 0.298023 + +Table: hashing by multiplication, double hashing, alpha: 0.5, s: 4 +Time: 18.4405s, size: 10000000, capacity: 67108864, alpha: 0.149012 + +Table: hashing by multiplication, double hashing, alpha: 0.75, s: 2 +Time: 15.5715s, size: 10000000, capacity: 16777216, alpha: 0.596046 +``` diff --git a/src/hashtable.h b/src/hashtable.h index 2d9133048099f24e2915a8b6393ceec49ddec134..02fd625a6b3c8c1b80641099a2898317b1e96fcd 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -11,34 +11,103 @@ template<typename T, typename H, typename P> class Hashtable; template<typename T> class Slot; +/** + * The hashtable as a template class. + * + * The table + * - stores keys of type T, + * - uses a function object of type H as hash function, and + * - a function object P for probing (collision resolution). + * + * (see hashing.h for hash functions / probing strategies) + * + */ template <typename T, typename H = DivHashing<T>, typename P = LinearProbing> class Hashtable { public: + /* + * The hashtable constructor. + * + * Creates a hashtable that + * - has an initial size m (m >= 0), + * - a maximal load factor alpha (0 < alpha < 1), and + * - grows by factor s when alpha gets exceeded (s > 1). + */ Hashtable(size_t m=8, float alpha=0.75, float s=2.0); + /* + * Inserts a key into the table. + * + * Returns + * - true if key was inserted, + * - false if key was already in the table. + */ bool insert(T key); + + /* + * Removes a key from the table. + * + * Returns + * - true if key was removed, + * - false if key was not found. + */ bool remove(T key); + + /* + * Queries the table for a key. + * + * Returns + * - true if key is in the table, + * - false otherwise. + */ bool contains(T key); + + /* + * Returns the number of keys that are currently stored in the table. + */ size_t size() const { return element_count; } + + /* + * Returns the number of keys the table can store (the currently allocated space). + */ size_t capacity() const { return slot_count; } + + /* + * Returns the load factor of the table (i.e. size/capacity). + */ float load_factor() const; + /* + * Returns some printable information about the table: size, capacity, load. + */ std::string info() const; + + /* + * Returns a vissual representation of the table. + */ std::string print() const; + private: size_t element_count = 0; size_t slot_count; const float max_loadfactor; const float growfactor; + + // pointer to the array that actually holds the data std::unique_ptr<Slot<T>[]> table; + // hashing and probing functions H hash; P probe; + // grows the table by grow factor s void grow(); }; -/* a bucket of size 1 */ +/** + * A slot in the table that holds a key of type T + * (a bucket of size 1). + */ template <typename T> class Slot { T key;