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.