Files Classes Functions Hierarchy
00001 #ifndef HASHTABLE_H 00002 #define HASHTABLE_H 00003 00004 #include <bucketlink.h> 00005 #include <typedefs.h> 00006 00039 template< typename T, typename HFN > 00040 class hashtable 00041 { 00042 public: 00043 00045 uint bucketsize; 00047 HFN fn; 00048 00052 bucketlink<T> * * vb; 00053 00054 typedef bucketlink<T> * blink; 00055 00058 hashtable 00059 ( 00060 uintc bucketsize_, 00061 HFN fn_ 00062 ); 00064 ~hashtable(); 00065 00067 hashtable() { bucketsize=0; }; 00068 00070 void construct(uintc bucketsize_); 00071 00074 void insert( bucketlink<T>* x ); 00075 00079 bucketlink<T>* insertInverse( T const & key ) const; 00080 00082 boolc remove( T const & key ); 00083 00085 boolc contains( T const & key ) const 00086 { return insertInverse(key)!=0; } 00087 00088 }; 00089 00093 template< typename H> 00094 class hashtableiterator 00095 { 00097 uint ci; 00099 typename H::blink cx; 00100 public: 00101 00103 H & ht; 00105 hashtableiterator(H & ht_) 00106 : ht(ht_) {} 00107 00109 void reset(); 00111 boolc operator ! () 00112 { return (cx!=0); } 00114 void operator ++ (); 00116 typename H::blink operator()() const 00117 { return cx; }; 00118 00119 }; 00120 00121 00122 //--------------------------------------------------------- 00123 // Implementation 00124 00125 template< typename H > 00126 void hashtableiterator<H>::reset() 00127 { 00128 ci=0; 00129 cx=ht.vb[0]; 00130 if (cx==0) 00131 ++(*this); 00132 } 00133 00134 template< typename H > 00135 void hashtableiterator<H>::operator ++ () 00136 { 00137 if (cx) 00138 { 00139 cx = cx->next; 00140 if (cx) 00141 return; 00142 00143 ++ci; 00144 } 00145 00146 for ( ; ci<ht.bucketsize; ++ci) 00147 { 00148 cx = ht.vb[ci]; 00149 if (cx==0) 00150 continue; 00151 00152 return; 00153 } 00154 } 00155 00156 template< typename T, typename HFN > 00157 bucketlink<T>* hashtable<T,HFN>::insertInverse 00158 ( 00159 T const & key 00160 ) const 00161 { 00162 assert(bucketsize!=0); 00163 00164 uint k = fn(key) % bucketsize; 00165 00166 bucketlink<T> * cp( vb[k] ); 00167 if (cp==0) 00168 return 0; 00169 00170 for ( ; cp!=0; cp = cp->next ) 00171 { 00172 if (*(cp->data) == key) 00173 return cp; 00174 } 00175 00176 return 0; 00177 } 00178 00179 template< typename T, typename HFN > 00180 boolc hashtable<T,HFN>::remove 00181 ( 00182 T const & key 00183 ) 00184 { 00185 assert(bucketsize!=0); 00186 00187 uint k = fn(key) % bucketsize; 00188 00189 //bucketlink<T> * cp( vb[k] ); 00190 blink cp( vb[k] ); 00191 if (cp==0) 00192 return false; 00193 00194 // Element to be removed at head of list. 00195 if (*(cp->data) == key) 00196 { 00197 vb[k] = cp->next; 00198 return true; 00199 } 00200 00201 blink prev=cp; 00202 cp=cp->next; 00203 for ( ; cp!=0; cp = cp->next ) 00204 { 00205 if (*(cp->data) == key) 00206 { 00207 prev->next = cp->next; 00208 return true; 00209 } 00210 00211 prev=cp; 00212 } 00213 00214 return false; 00215 } 00216 00217 template< typename T, typename HFN > 00218 void hashtable<T,HFN>::insert( bucketlink<T>* x ) 00219 { 00220 if(x==0) 00221 return; 00222 00223 assert(bucketsize!=0); 00224 00225 uint k = fn( * x->data ) % bucketsize; 00226 00227 bucketlink<T> * cp( vb[k] ); 00228 if (cp==0) 00229 { 00230 vb[k] = x; 00231 return; 00232 } 00233 00234 // Insert at the head of the list. 00235 x->next = cp; 00236 vb[k] = x; 00237 } 00238 00239 template< typename T, typename HFN > 00240 hashtable<T,HFN>::hashtable 00241 ( 00242 uintc bucketsize_, 00243 HFN fn_ 00244 ) 00245 : bucketsize(bucketsize_), fn(fn_) 00246 { 00247 vb = new bucketlink<T> * [bucketsize]; 00248 for (uint i=0; i<bucketsize; ++i) 00249 vb[i]=0; 00250 } 00251 00252 template< typename T, typename HFN > 00253 hashtable<T,HFN>::~hashtable() 00254 { 00255 delete[] vb; 00256 vb=0; 00257 } 00258 00259 template< typename T, typename HFN > 00260 void hashtable<T,HFN>::construct(uintc bucketsize_) 00261 { 00262 bucketsize = bucketsize_; 00263 delete[] vb; 00264 vb = new bucketlink<T> * [bucketsize]; 00265 for (uint i=0; i<bucketsize; ++i) 00266 vb[i]=0; 00267 } 00268 00269 #endif 00270
1.5.8