// ================================================================================ // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås == // == See tb_core.h for more information. == // ================================================================================ #ifndef TB_HASHTABLE_H #define TB_HASHTABLE_H #include "tb_core.h" #include namespace tb { /** TBHashTable is a minimal hash table, for hashing anything using a uint32 key. */ class TBHashTable { public: TBHashTable(); virtual ~TBHashTable(); /** Remove all items without deleting the content. */ void RemoveAll() { RemoveAll(false); } /** Remove all items and delete the content. This requires TBHashTable to be subclassed and implementing DeleteContent. You would typically do this by using TBHashTableOf or TBHashTableAutoDeleteOf. */ void DeleteAll() { RemoveAll(true); } /** Get the content for the given key, or nullptr if not found. */ void *Get(uint32 key) const; /** Add content with the given key. Returns false if out of memory. */ bool Add(uint32 key, void *content); /** Remove the content with the given key. */ void *Remove(uint32 key); /** Delete the content with the given key. */ void Delete(uint32 key); /** Rehash the table so use the given number of buckets. Returns false if out of memory. */ bool Rehash(uint32 num_buckets); /** Return true if the hashtable itself think it's time to rehash. */ bool NeedRehash() const; /** Get the number of buckets the hashtable itself thinks is suitable for the current number of items. */ uint32 GetSuitableBucketsCount() const; /** Get the number of items in the hash table. */ uint32 GetNumItems() const { return m_num_items; } #ifdef TB_RUNTIME_DEBUG_INFO /** Print out some debug info about the hash table. */ void Debug(); #endif protected: /** Delete the content of a item. This is called if calling DeleteAll, and must be implemented in a subclass that knows about the content type. */ virtual void DeleteContent(void *content) { assert(!"You need to subclass and implement!"); } private: friend class TBHashTableIterator; void RemoveAll(bool delete_content); struct ITEM { uint32 key; ITEM *next; void *content; } **m_buckets; uint32 m_num_buckets; uint32 m_num_items; }; /** TBHashTableIterator is a iterator for stepping through all content stored in a TBHashTable. */ //FIX: make it safe in case the current item is removed from the hashtable class TBHashTableIterator { public: TBHashTableIterator(TBHashTable *hash_table); void *GetNextContent(); private: TBHashTable *m_hash_table; uint32 m_current_bucket; TBHashTable::ITEM *m_current_item; }; /** TBHashTableIteratorOf is a TBHashTableIterator which auto cast to the class type. */ template class TBHashTableIteratorOf : private TBHashTableIterator { public: TBHashTableIteratorOf(TBHashTable *hash_table) : TBHashTableIterator(hash_table) {} T *GetNextContent() { return (T*) TBHashTableIterator::GetNextContent(); } }; /** TBHashTableOf is a TBHashTable with the given class type as content. */ template class TBHashTableOf : public TBHashTable { // FIX: Don't do public inheritance! Either inherit privately and forward, or use a private member backend! public: T *Get(uint32 key) const { return (T*) TBHashTable::Get(key); } T *Remove(uint32 key) { return (T*) TBHashTable::Remove(key); } protected: virtual void DeleteContent(void *content) { delete (T*) content; } }; /** TBHashTableOf is a TBHashTable with the given class type as content. It will delete all content automaticallt on destruction. */ template class TBHashTableAutoDeleteOf : public TBHashTable { public: ~TBHashTableAutoDeleteOf() { DeleteAll(); } T *Get(uint32 key) const { return (T*) TBHashTable::Get(key); } protected: virtual void DeleteContent(void *content) { delete (T*) content; } }; } // namespace tb #endif // TB_HASHTABLE_H