Loading CuckooHash/CuckooHashMap.h +5 −6 Original line number Diff line number Diff line Loading @@ -5,17 +5,17 @@ #include "../Pair.hpp" template<typename K, typename V> class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K> { template<typename K, typename V, typename Device = TNL::Devices::Host> class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K, Device> { public: ///< Copy constructor CuckooHashMap(const CuckooHashMap<K, V>& other); CuckooHashMap(const CuckooHashMap<K, V, Device>& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashMap(const std::vector<std::pair<K, V>>& values = {}, const std::pair<K, V>& defPair = {K(), V()}, uint8_t nHashFunctions = 6); CuckooHashMap(const Array<Pair<K, V>, Device>& values = {}, uint8_t nHashFunctions = 6); /**Constructor * Loading @@ -25,8 +25,7 @@ class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K> { * values - vector of <key, value> pairs to populate the table */ CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values = {}, const std::pair<K, V>& defItem = {K(), V()}); const std::vector<std::pair<K, V>>& values = {}); /**Find a given key in the table if it exists * If the key is found, return true and write the related value into 'value' out-parameter Loading CuckooHash/CuckooHashMap.hpp +20 −26 Original line number Diff line number Diff line Loading @@ -5,32 +5,26 @@ #include <TNL/Containers/StaticArray.h> template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(const CuckooHashMap<K, V>& other) : CuckooHashTable<Pair<K, V>, K>(other) {} template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(const CuckooHashMap<K, V, Device>& other) : CuckooHashTable<Pair<K, V>, K, Device>(other) {} template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(const std::vector<std::pair<K, V>>& values, const std::pair<K, V>& defPair, uint8_t nHashFunctions) : CuckooHashTable<Pair<K, V>, K>(std::move(Pair<K, V>::fill(values)), defPair, nHashFunctions) {} template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(const Array<Pair<K, V>, Device>& values, uint8_t nHashFunctions) : CuckooHashTable<Pair<K, V>, K, Device>(values, nHashFunctions) {} template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values, const std::pair<K, V>& defItem) : CuckooHashTable<Pair<K, V>, K>(tableSize, template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values) : CuckooHashTable<Pair<K, V>, K, Device>(tableSize, nHashFunctions, nIters, std::move(Pair<K, V>::fill(values)), std::move(Pair<K, V>(defItem))) {} Pair<K, V>::template fill<Device>(values)) {} template<typename K, typename V> bool CuckooHashMap<K, V>::find(const K& key, V& value) const { Pair<K, V> pair(this->m_default); if (!CuckooHashTable<Pair<K, V>, K>::find(key, &pair)) template<typename K, typename V, typename Device> bool CuckooHashMap<K, V, Device>::find(const K& key, V& value) const { Array<Pair<K, V>, Device> item(1); if (!this->m_view->find(key, item.getView())) return false; value = pair.pair.second; value = item.getElement(0).value; return true; } template class CuckooHashMap<std::string, std::string>; template class CuckooHashMap<TNL::Containers::StaticArray<3, int>, int>; CuckooHash/CuckooHashSet.h +9 −8 Original line number Diff line number Diff line Loading @@ -4,22 +4,25 @@ #include "../Value.hpp" #include <TNL/Containers/Vector.hpp> #include <TNL/Containers/Array.hpp> using namespace TNL::Containers; template<typename T> class CuckooHashSet : public CuckooHashTable<Value<T>, T> { template<typename T, typename Device = TNL::Devices::Host> class CuckooHashSet : public CuckooHashTable<Value<T>, T, Device> { public: ///< Copy constructor CuckooHashSet(const CuckooHashSet<T>& other); CuckooHashSet(const CuckooHashSet<T, Device>& other); ///< Move constructor CuckooHashSet(CuckooHashSet<T, Device>&& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashSet(const std::vector<T>& values = {}, const T& defValue = T(), uint8_t nHashFunctions = 6); CuckooHashSet(const Array<T, Device>& values = {}, uint8_t nHashFunctions = 6); /**Constructor * Loading @@ -28,10 +31,8 @@ class CuckooHashSet : public CuckooHashTable<Value<T>, T> { * nIters - maximal number of insertion attempts before starting over with regenerated hash functions * values - vector of values to populate the table */ CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<T>& values = {}, const T& defValue = T()); const Array<T, Device>& values = {}); ///< Check if given key exists in the table bool contains(const T& value) const; Loading CuckooHash/CuckooHashSet.hpp +22 −19 Original line number Diff line number Diff line Loading @@ -5,23 +5,26 @@ #include <TNL/Containers/StaticArray.h> template<typename T> CuckooHashSet<T>::CuckooHashSet(const CuckooHashSet<T>& other) : CuckooHashTable<Value<T>, T>(other) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(const CuckooHashSet<T, Device>& other) : CuckooHashTable<Value<T>, T, Device>(other) {} template<typename T> CuckooHashSet<T>::CuckooHashSet(const std::vector<T>& values, const T& defValue, uint8_t nHashFunctions) : CuckooHashTable<Value<T>, T>(std::move(Value<T>::fill(values)), defValue, nHashFunctions) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(CuckooHashSet<T, Device>&& other) : CuckooHashTable<Value<T>, T, Device>(other) {} template<typename T> CuckooHashSet<T>::CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<T>& values, const T& defValue) : CuckooHashTable<Value<T>, T>(tableSize, template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(const Array<T, Device>& values, uint8_t nHashFunctions) : CuckooHashTable<Value<T>, T, Device>(Value<T>::template fill<Device>(values), nHashFunctions) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const Array<T, Device>& values) : CuckooHashTable<Value<T>, T, Device>(tableSize, nHashFunctions, nIters, std::move(Value<T>::fill(values)), std::move(Value<T>(defValue))) {} std::move(Value<T>::fill(values))) {} template<typename T> bool CuckooHashSet<T>::contains(const T& value) const { return CuckooHashTable<Value<T>, T>::find(value); template<typename T, typename Device> bool CuckooHashSet<T, Device>::contains(const T& value) const { Array<Value<T>, Device> item(1); return this->m_view->find(value, item.getView()); } CuckooHash/CuckooHashTable.h +32 −34 Original line number Diff line number Diff line #pragma once #include "../HashFunction.h" #include "CuckooHashTableView.h" #include <TNL/Containers/Array.h> #include <cstdint> #include <iostream> #include <functional> #include <vector> Loading @@ -16,29 +18,43 @@ using namespace TNL::Containers; * K - type of keys * V - type of values */ template<typename Item, typename Key> template<typename Item, typename Key, typename Device> class CuckooHashTable { struct Entry { bool occupied; int hashFunction; Item item; }; using Self = CuckooHashTable<Item, Key, Device>; using ViewType = CuckooHashTableView<Item, Key, Device>; using Entry = typename ViewType::Entry; friend ViewType::CuckooHashTableView(Self&, const typename Array<Item, Device>::ConstViewType); public: ///< Reports the number of performed attempts to build the table int generations() const; ///< Reports the number of attempts to insert duplicates while building the table int duplicates() const; void debug_print() { for (int i = 0; i < m_table.getSize(); i++) { auto entry = m_table.getElement(i); if (entry >= 0) std::cout << i << ' ' << m_content.getElement(entry).item.key /*<< ' ' << m_content.getElement(entry.item).value*/ << std::endl; else std::cout << i << ' ' << "Not occupied" << std::endl; } } protected: ///< Copy constructor CuckooHashTable(const CuckooHashTable<Item, Key>& other); CuckooHashTable(const CuckooHashTable<Item, Key, Device>& other); ///< Move constructor CuckooHashTable(CuckooHashTable<Item, Key, Device>&& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashTable(const Array<Item>& values = {}, const Item& defItem = Item(), uint8_t nHashFunctions = 6); CuckooHashTable(const Array<Item, Device>& values, uint8_t nHashFunctions); /**Constructor * Loading @@ -48,38 +64,20 @@ class CuckooHashTable { * values - vector of <key, value> pairs to populate the table */ CuckooHashTable(int tableSize, uint8_t nHashFunctions, int nIters, const Array<Item>& values = {}, const Item& defItem = Item()); const Array<Item, Device>& values = {}); ///< Copy assignment CuckooHashTable<Item, Key>& operator=(const CuckooHashTable<Item, Key>& other); ///< Destuctor ~CuckooHashTable(); CuckooHashTable<Item, Key, Device>& operator=(const CuckooHashTable<Item, Key, Device>& other); //! Find and return item having provided key bool find(const Key& key, Item* result = nullptr) const; Array<HashFunction<Key>> m_hashFunctions; Array<Entry> m_table; const Item m_default; Array<HashFunction<Key>, Device> m_hashFunctions; Array<int, Device> m_table; Array<Entry, Device> m_content; private: //! Populate the table with given values, regenerate hash functions on each failure void build(const Array<Item>& values, uint8_t nHashFunctions); //! Randomly generate hash functions void init_hash_functions(); //! Initialize table with empty rows void clear_table(); /**Inserts a new item into the table * Returns true if insertion is successful (didn't reach maximum number of iterations) */ bool insert(Item item, bool& duplicate); int m_iterations; int m_generations; int m_duplicates; protected: std::shared_ptr<ViewType> m_view; }; Loading Loading
CuckooHash/CuckooHashMap.h +5 −6 Original line number Diff line number Diff line Loading @@ -5,17 +5,17 @@ #include "../Pair.hpp" template<typename K, typename V> class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K> { template<typename K, typename V, typename Device = TNL::Devices::Host> class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K, Device> { public: ///< Copy constructor CuckooHashMap(const CuckooHashMap<K, V>& other); CuckooHashMap(const CuckooHashMap<K, V, Device>& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashMap(const std::vector<std::pair<K, V>>& values = {}, const std::pair<K, V>& defPair = {K(), V()}, uint8_t nHashFunctions = 6); CuckooHashMap(const Array<Pair<K, V>, Device>& values = {}, uint8_t nHashFunctions = 6); /**Constructor * Loading @@ -25,8 +25,7 @@ class CuckooHashMap : public CuckooHashTable<Pair<K, V>, K> { * values - vector of <key, value> pairs to populate the table */ CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values = {}, const std::pair<K, V>& defItem = {K(), V()}); const std::vector<std::pair<K, V>>& values = {}); /**Find a given key in the table if it exists * If the key is found, return true and write the related value into 'value' out-parameter Loading
CuckooHash/CuckooHashMap.hpp +20 −26 Original line number Diff line number Diff line Loading @@ -5,32 +5,26 @@ #include <TNL/Containers/StaticArray.h> template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(const CuckooHashMap<K, V>& other) : CuckooHashTable<Pair<K, V>, K>(other) {} template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(const CuckooHashMap<K, V, Device>& other) : CuckooHashTable<Pair<K, V>, K, Device>(other) {} template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(const std::vector<std::pair<K, V>>& values, const std::pair<K, V>& defPair, uint8_t nHashFunctions) : CuckooHashTable<Pair<K, V>, K>(std::move(Pair<K, V>::fill(values)), defPair, nHashFunctions) {} template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(const Array<Pair<K, V>, Device>& values, uint8_t nHashFunctions) : CuckooHashTable<Pair<K, V>, K, Device>(values, nHashFunctions) {} template<typename K, typename V> CuckooHashMap<K, V>::CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values, const std::pair<K, V>& defItem) : CuckooHashTable<Pair<K, V>, K>(tableSize, template<typename K, typename V, typename Device> CuckooHashMap<K, V, Device>::CuckooHashMap(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<std::pair<K, V>>& values) : CuckooHashTable<Pair<K, V>, K, Device>(tableSize, nHashFunctions, nIters, std::move(Pair<K, V>::fill(values)), std::move(Pair<K, V>(defItem))) {} Pair<K, V>::template fill<Device>(values)) {} template<typename K, typename V> bool CuckooHashMap<K, V>::find(const K& key, V& value) const { Pair<K, V> pair(this->m_default); if (!CuckooHashTable<Pair<K, V>, K>::find(key, &pair)) template<typename K, typename V, typename Device> bool CuckooHashMap<K, V, Device>::find(const K& key, V& value) const { Array<Pair<K, V>, Device> item(1); if (!this->m_view->find(key, item.getView())) return false; value = pair.pair.second; value = item.getElement(0).value; return true; } template class CuckooHashMap<std::string, std::string>; template class CuckooHashMap<TNL::Containers::StaticArray<3, int>, int>;
CuckooHash/CuckooHashSet.h +9 −8 Original line number Diff line number Diff line Loading @@ -4,22 +4,25 @@ #include "../Value.hpp" #include <TNL/Containers/Vector.hpp> #include <TNL/Containers/Array.hpp> using namespace TNL::Containers; template<typename T> class CuckooHashSet : public CuckooHashTable<Value<T>, T> { template<typename T, typename Device = TNL::Devices::Host> class CuckooHashSet : public CuckooHashTable<Value<T>, T, Device> { public: ///< Copy constructor CuckooHashSet(const CuckooHashSet<T>& other); CuckooHashSet(const CuckooHashSet<T, Device>& other); ///< Move constructor CuckooHashSet(CuckooHashSet<T, Device>&& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashSet(const std::vector<T>& values = {}, const T& defValue = T(), uint8_t nHashFunctions = 6); CuckooHashSet(const Array<T, Device>& values = {}, uint8_t nHashFunctions = 6); /**Constructor * Loading @@ -28,10 +31,8 @@ class CuckooHashSet : public CuckooHashTable<Value<T>, T> { * nIters - maximal number of insertion attempts before starting over with regenerated hash functions * values - vector of values to populate the table */ CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<T>& values = {}, const T& defValue = T()); const Array<T, Device>& values = {}); ///< Check if given key exists in the table bool contains(const T& value) const; Loading
CuckooHash/CuckooHashSet.hpp +22 −19 Original line number Diff line number Diff line Loading @@ -5,23 +5,26 @@ #include <TNL/Containers/StaticArray.h> template<typename T> CuckooHashSet<T>::CuckooHashSet(const CuckooHashSet<T>& other) : CuckooHashTable<Value<T>, T>(other) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(const CuckooHashSet<T, Device>& other) : CuckooHashTable<Value<T>, T, Device>(other) {} template<typename T> CuckooHashSet<T>::CuckooHashSet(const std::vector<T>& values, const T& defValue, uint8_t nHashFunctions) : CuckooHashTable<Value<T>, T>(std::move(Value<T>::fill(values)), defValue, nHashFunctions) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(CuckooHashSet<T, Device>&& other) : CuckooHashTable<Value<T>, T, Device>(other) {} template<typename T> CuckooHashSet<T>::CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const std::vector<T>& values, const T& defValue) : CuckooHashTable<Value<T>, T>(tableSize, template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(const Array<T, Device>& values, uint8_t nHashFunctions) : CuckooHashTable<Value<T>, T, Device>(Value<T>::template fill<Device>(values), nHashFunctions) {} template<typename T, typename Device> CuckooHashSet<T, Device>::CuckooHashSet(int tableSize, uint8_t nHashFunctions, int nIters, const Array<T, Device>& values) : CuckooHashTable<Value<T>, T, Device>(tableSize, nHashFunctions, nIters, std::move(Value<T>::fill(values)), std::move(Value<T>(defValue))) {} std::move(Value<T>::fill(values))) {} template<typename T> bool CuckooHashSet<T>::contains(const T& value) const { return CuckooHashTable<Value<T>, T>::find(value); template<typename T, typename Device> bool CuckooHashSet<T, Device>::contains(const T& value) const { Array<Value<T>, Device> item(1); return this->m_view->find(value, item.getView()); }
CuckooHash/CuckooHashTable.h +32 −34 Original line number Diff line number Diff line #pragma once #include "../HashFunction.h" #include "CuckooHashTableView.h" #include <TNL/Containers/Array.h> #include <cstdint> #include <iostream> #include <functional> #include <vector> Loading @@ -16,29 +18,43 @@ using namespace TNL::Containers; * K - type of keys * V - type of values */ template<typename Item, typename Key> template<typename Item, typename Key, typename Device> class CuckooHashTable { struct Entry { bool occupied; int hashFunction; Item item; }; using Self = CuckooHashTable<Item, Key, Device>; using ViewType = CuckooHashTableView<Item, Key, Device>; using Entry = typename ViewType::Entry; friend ViewType::CuckooHashTableView(Self&, const typename Array<Item, Device>::ConstViewType); public: ///< Reports the number of performed attempts to build the table int generations() const; ///< Reports the number of attempts to insert duplicates while building the table int duplicates() const; void debug_print() { for (int i = 0; i < m_table.getSize(); i++) { auto entry = m_table.getElement(i); if (entry >= 0) std::cout << i << ' ' << m_content.getElement(entry).item.key /*<< ' ' << m_content.getElement(entry.item).value*/ << std::endl; else std::cout << i << ' ' << "Not occupied" << std::endl; } } protected: ///< Copy constructor CuckooHashTable(const CuckooHashTable<Item, Key>& other); CuckooHashTable(const CuckooHashTable<Item, Key, Device>& other); ///< Move constructor CuckooHashTable(CuckooHashTable<Item, Key, Device>&& other); /**Constructor * values - vector of <key, value> pairs to populate the table * nHashFunctions = number of hash functions to generate and use */ CuckooHashTable(const Array<Item>& values = {}, const Item& defItem = Item(), uint8_t nHashFunctions = 6); CuckooHashTable(const Array<Item, Device>& values, uint8_t nHashFunctions); /**Constructor * Loading @@ -48,38 +64,20 @@ class CuckooHashTable { * values - vector of <key, value> pairs to populate the table */ CuckooHashTable(int tableSize, uint8_t nHashFunctions, int nIters, const Array<Item>& values = {}, const Item& defItem = Item()); const Array<Item, Device>& values = {}); ///< Copy assignment CuckooHashTable<Item, Key>& operator=(const CuckooHashTable<Item, Key>& other); ///< Destuctor ~CuckooHashTable(); CuckooHashTable<Item, Key, Device>& operator=(const CuckooHashTable<Item, Key, Device>& other); //! Find and return item having provided key bool find(const Key& key, Item* result = nullptr) const; Array<HashFunction<Key>> m_hashFunctions; Array<Entry> m_table; const Item m_default; Array<HashFunction<Key>, Device> m_hashFunctions; Array<int, Device> m_table; Array<Entry, Device> m_content; private: //! Populate the table with given values, regenerate hash functions on each failure void build(const Array<Item>& values, uint8_t nHashFunctions); //! Randomly generate hash functions void init_hash_functions(); //! Initialize table with empty rows void clear_table(); /**Inserts a new item into the table * Returns true if insertion is successful (didn't reach maximum number of iterations) */ bool insert(Item item, bool& duplicate); int m_iterations; int m_generations; int m_duplicates; protected: std::shared_ptr<ViewType> m_view; }; Loading