HashTable.hpp

Go to the documentation of this file.
00001 /*
00002 SagaEngine library
00003 Copyright (c) 2002-2006 Skalden Studio AS
00004 
00005 This software is provided 'as-is', without any express or implied 
00006 warranty. In no event will the authors be held liable for any 
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to distribute the library under the terms of the 
00010 Q Public License version 1.0. Be sure to read and understand the license
00011 before using the library. It should be included here, or you may read it
00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl
00013 
00014 The original version of this library can be located at:
00015 http://www.sagaengine.com/
00016 
00017 Rune Myrland
00018 rune@skalden.com
00019 */
00020 
00021 
00022 #ifndef base_template_HashTable_hpp
00023 #define base_template_HashTable_hpp
00024 
00025 #include "SinglyLinkedList.hpp"
00026 #include "util/error/Log.hpp"
00027 
00028 namespace se_core {
00029 
00030     template <class T, int poolSize> class HashTable {
00031     protected:
00032         enum {
00033             DEFAULT_HASH_TABLE_SIZE = 16
00034         };
00035 
00036     public:
00037         class HashTableNode {
00038         public:
00039             short key_;
00040             T* data_;
00041 
00042             HashTableNode(short key, T* new_data)
00043                 : key_(key), data_(new_data) {
00044             }
00045         };
00046 
00047         struct NodeList
00048                 : public SinglyLinkedList<HashTableNode, poolSize, 97> {
00049             NodeList(const char* name) : SinglyLinkedList<HashTableNode, poolSize, 97>(name) {
00050             }
00051         };
00052         typedef int iterator_type;
00053 
00054 
00055 
00056         HashTable()
00057                 : count_(0) {
00058             initialize();
00059         }
00060 
00061         HashTable(int size)
00062                 : count_(0) {
00063             initialize(size);
00064         }
00065 
00066         //HashTable(const HashTable& source) {
00067         //  copy(source);
00068         //}
00069 
00070 
00071         virtual ~HashTable() {
00072             if(hashTable_) {
00073                 // For all hash lists
00074                 for(int i = 0; i < tableSize(); ++i) {
00075                     // delete HashNode's
00076                     iterator_type it;
00077                     it = hashTable_[i];
00078                     while(it != NodeList::end()) {
00079                         delete nodeList().next(it);
00080                     }
00081                     it = hashTable_[i];
00082                     // remove link chain from nodeList
00083                     nodeList().removeChain(it);
00084                 }
00085                 delete [] hashTable_;
00086             }
00087         }
00088 
00089 
00090         void initialize(int size = DEFAULT_HASH_TABLE_SIZE) {
00091             hashTable_ = new iterator_type[size];
00092             tableSize_ = size;
00093             for(int i = 0; i < tableSize_; ++i) {
00094                 hashTable_[i] = NodeList::end();
00095             }
00096         }
00097 
00098 
00099         unsigned int hash(short key) {
00100             return key;
00101         }
00102 
00103 
00104         // insert key into hash table.
00105         // returns pointer to old data with the key, if any, or
00106         // NULL if the key wasn't in the table previously.
00107         T* add(short key, T* data) {
00108             if(!hashTable_)
00109                 return 0;
00110 
00111             unsigned int index = hash(key) % tableSize();
00112             HashTableNode* newNode = new HashTableNode(key, data);
00113             nodeList().add(*newNode, hashTable_[ index ]);
00114             ++count_;
00115             return newNode->data_;
00116         }
00117 
00118 
00119         T* lookup(short key) {
00120             if(!hashTable_)
00121                 return 0;
00122 
00123             HashTableNode* node = lookupNode(key);
00124 
00125             if(node)
00126                 return node->data_;
00127 
00128             return 0;
00129         }
00130 
00131 
00132         // returns the list that contains this hash key...
00133         // (for instance, if you have multiple matching keys)
00134         iterator_type lookupList(short key) {
00135             if(!hashTable_)
00136                 return -1;
00137             unsigned int index = hash(key) % tableSize();
00138             return hashTable_[index];
00139         }
00140 
00141 
00142         T* remove(short key) {
00143             if(!hashTable_)
00144                 return 0;
00145 
00146             unsigned int index = hash(key) % tableSize_;
00147 
00148             iterator_type walker = hashTable_[index];
00149             while( walker != NodeList::end() ) {
00150                 HashTableNode* v = nodeList().next(walker);
00151                 if(v->key_ == key) {
00152                     T* return_value = v->data_;
00153                     nodeList().remove(*v, hashTable_[ index ]);
00154                     delete v;
00155                     --count_;
00156                     return return_value;
00157                 }
00158             }
00159 
00160             return 0;
00161         }
00162 
00163 
00164         iterator_type hashTable(int index) {
00165             return hashTable_[index];
00166         }
00167 
00168 
00169         NodeList& nodeList() {
00170             static NodeList singleton(__FILE__);
00171             return singleton;
00172         }
00173 
00174 
00175         int tableSize() {
00176             return tableSize_;
00177         }
00178 
00179 
00180         int count() {
00181             return count_;
00182         }
00183 
00184 
00185     protected:
00186         HashTableNode* lookupNode(short key) {
00187             unsigned int index = hash(key) % tableSize();
00188             HashTableNode* ret = 0;
00189 
00190             iterator_type walker;
00191             walker = hashTable_[index];
00192 
00193             while(walker != NodeList::end()) {
00194                 HashTableNode* v = nodeList().next(walker);
00195                 if(v->key_ == key) {
00196                     ret = v;
00197                     break;
00198                 }
00199             }
00200 
00201             return ret;
00202         }
00203 
00204         iterator_type* hashTable_;
00205         int tableSize_;
00206         int count_;
00207 
00208     private:
00209         // declared to prevent unintentional use...
00210         // (Don't forget to move to public access if you declare them!)
00211         HashTable& Copy(const HashTable& source_object) { return *this; }
00212         HashTable& operator= (const HashTable& source_object) { return *this; }
00213     };
00214 }
00215 
00216 #endif

Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:12 2007 by Doxygen version 1.3.9.1.

SourceForge.net Logo