sc_hash.h revision 12027:1eb7dc7aa10b
1/***************************************************************************** 2 3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 4 more contributor license agreements. See the NOTICE file distributed 5 with this work for additional information regarding copyright ownership. 6 Accellera licenses this file to you under the Apache License, Version 2.0 7 (the "License"); you may not use this file except in compliance with the 8 License. You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12 Unless required by applicable law or agreed to in writing, software 13 distributed under the License is distributed on an "AS IS" BASIS, 14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 15 implied. See the License for the specific language governing 16 permissions and limitations under the License. 17 18 *****************************************************************************/ 19 20/***************************************************************************** 21 22 sc_hash.cpp -- Implementation of a chained hash table with MTF 23 (move-to-front). 24 25 Original Author: Stan Y. Liao, Synopsys, Inc. 26 27 CHANGE LOG AT END OF FILE 28 *****************************************************************************/ 29 30#ifndef SC_HASH_H 31#define SC_HASH_H 32 33 34namespace sc_core { 35 36extern unsigned default_int_hash_fn(const void*); 37extern unsigned default_ptr_hash_fn(const void*); 38extern unsigned default_str_hash_fn(const void*); 39 40class sc_phash_elem; 41class sc_phash_base_iter; 42template<class K, class C> //template class 43class sc_pdhash_iter; //decl. -- Amit 44 45const int PHASH_DEFAULT_MAX_DENSITY = 5; 46const int PHASH_DEFAULT_INIT_TABLE_SIZE = 11; 47extern const double PHASH_DEFAULT_GROW_FACTOR; 48const bool PHASH_DEFAULT_REORDER_FLAG = true; 49 50class sc_phash_base { 51 friend class sc_phash_base_iter; 52 53 typedef sc_phash_base_iter iterator; 54 55public: 56 typedef unsigned (*hash_fn_t)(const void*); 57 typedef int (*cmpr_fn_t)(const void*, const void*); 58 59protected: 60 void* default_value; 61 int num_bins; 62 int num_entries; 63 int max_density; 64 int reorder_flag; 65 double grow_factor; 66 67 sc_phash_elem** bins; 68 69 hash_fn_t hash; 70 cmpr_fn_t cmpr; 71 72 void rehash(); 73 unsigned do_hash(const void* key) const { return (*hash)(key) % num_bins; } 74 75 sc_phash_elem* add_direct(void* key, void* contents, unsigned hash_val); 76 sc_phash_elem* find_entry_c(unsigned hv, const void* k, sc_phash_elem*** plast); 77 sc_phash_elem* find_entry_q(unsigned hv, const void* k, sc_phash_elem*** plast); 78 sc_phash_elem* find_entry(unsigned hv, const void* k, sc_phash_elem*** plast=0) const 79 { 80 /* Got rid of member func. pointer and replaced with if-else */ 81 /* Amit (5/14/99) */ 82 if( cmpr == 0 ) 83 return ((sc_phash_base*)this)->find_entry_q( hv, k, plast ); 84 else 85 return ((sc_phash_base*)this)->find_entry_c( hv, k, plast ); 86 } 87 88public: 89 sc_phash_base( void* def = 0, 90 int size = PHASH_DEFAULT_INIT_TABLE_SIZE, 91 int density = PHASH_DEFAULT_MAX_DENSITY, 92 double grow = PHASH_DEFAULT_GROW_FACTOR, 93 bool reorder = PHASH_DEFAULT_REORDER_FLAG, 94 hash_fn_t hash_fn = default_ptr_hash_fn, 95 cmpr_fn_t cmpr_fn = 0 ); 96 ~sc_phash_base(); 97 98 void set_cmpr_fn(cmpr_fn_t); 99 void set_hash_fn(hash_fn_t); 100 101 bool empty() const { return (num_entries == 0); } 102 unsigned count() const { return num_entries; } 103 104 void erase(); 105 void erase(void (*kfree)(void*)); 106 void copy( const sc_phash_base* ); 107 void copy( const sc_phash_base& b ) { copy(&b); } 108 void copy( const sc_phash_base& b, void* (*kdup)(const void*), void (*kfree)(void*)); 109 int insert( void* k, void* c ); 110 int insert( void* k ) { return insert(k, default_value); } 111 int insert( void* k, void* c, void* (*kdup)(const void*) ); 112 int insert_if_not_exists(void* k, void* c); 113 int insert_if_not_exists(void* k) { return insert_if_not_exists(k, default_value); } 114 int insert_if_not_exists(void* k, void* c, void* (*kdup)(const void*)); 115 int remove(const void* k); 116 int remove(const void* k, void** pk, void** pc); 117 int remove(const void* k, void (*kfree)(void*)); 118 int remove_by_contents(const void* c); 119 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg); 120 int remove_by_contents(const void* c, void (*kfree)(void*)); 121 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)); 122 int lookup(const void* k, void** pc) const; 123 bool contains(const void* k) const { return (lookup(k, 0) != 0); } 124 void* operator[](const void* key) const; 125}; 126 127class sc_phash_base_iter { 128protected: 129 sc_phash_base* table; 130 sc_phash_elem* entry; 131 sc_phash_elem* next; 132 sc_phash_elem** last; 133 int index; 134 135public: 136 void reset(sc_phash_base* t); 137 void reset(sc_phash_base& t) { reset(&t); } 138 139 sc_phash_base_iter(sc_phash_base* t) 140 : table(t), entry(0), next(0), last(0), index(0) 141 { reset(t); } 142 sc_phash_base_iter(sc_phash_base& t) 143 : table(&t), entry(0), next(0), last(0), index(0) 144 { reset(t); } 145 ~sc_phash_base_iter() { } 146 147 bool empty() const; 148 void step(); 149 void operator++(int) { step(); } 150 void remove(); 151 void remove(void (*kfree)(void*)); 152 void* key() const; 153 void* contents() const; 154 void* set_contents(void* c); 155}; 156 157template< class K, class C > 158class sc_phash_iter; 159 160template< class K, class C > 161class sc_phash : public sc_phash_base { 162 friend class sc_phash_iter<K,C>; 163 164public: 165 typedef sc_phash_iter<K,C> iterator; 166 167 sc_phash( C def = (C) 0, 168 int size = PHASH_DEFAULT_INIT_TABLE_SIZE, 169 int density = PHASH_DEFAULT_MAX_DENSITY, 170 double grow = PHASH_DEFAULT_GROW_FACTOR, 171 bool reorder = PHASH_DEFAULT_REORDER_FLAG, 172 hash_fn_t hash_fn = default_ptr_hash_fn, 173 cmpr_fn_t cmpr_fn = 0 ) 174 : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) { } 175 ~sc_phash() { } 176 177 void copy(const sc_phash<K,C>* b) { sc_phash_base::copy(b); } 178 void copy(const sc_phash<K,C>& b) { sc_phash_base::copy(b); } 179 void copy(const sc_phash<K,C>& b, void* (*kdup)(const void*), void (*kfree)(void*)) { sc_phash_base::copy(b, kdup, kfree); } 180 181 int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c); } 182 int insert(K k) { return sc_phash_base::insert((void*) k, default_value); } 183 int insert(K k, C c, void* (*kdup)(const void*)) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } 184 int insert_if_not_exists(K k, C c) 185 { 186 return sc_phash_base::insert_if_not_exists((void*) k, (void*) c); 187 } 188 int insert_if_not_exists(K k) 189 { 190 return sc_phash_base::insert_if_not_exists((void*) k, default_value); 191 } 192 int insert_if_not_exists(K k, C c, void* (*kdup)(const void*)) 193 { 194 return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); 195 } 196 int remove(K k) { return sc_phash_base::remove((const void*) k); } 197 int remove(K k, K* pk, C* pc) 198 { 199 return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); 200 } 201 int remove(K k, void (*kfree)(void*)) 202 { 203 return sc_phash_base::remove((const void*) k, kfree); 204 } 205 int remove_by_contents(C c) 206 { 207 return sc_phash_base::remove_by_contents((const void*) c); 208 } 209 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) 210 { 211 return sc_phash_base::remove_by_contents(predicate, arg); 212 } 213 int remove_by_contents(const void* c, void (*kfree)(void*)) 214 { 215 return sc_phash_base::remove_by_contents(c, kfree); 216 } 217 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg, void (*kfree)(void*)) 218 { 219 return sc_phash_base::remove_by_contents(predicate, arg, kfree); 220 } 221 int lookup(K k, C* pc) const 222 { 223 return sc_phash_base::lookup((const void*) k, (void**) pc); 224 } 225 bool contains(K k) const 226 { 227 return sc_phash_base::contains((const void*) k); 228 } 229 C operator[](K k) const 230 { 231 return (C) sc_phash_base::operator[]((const void*) k); 232 } 233}; 234 235 236template< class K, class C > 237class sc_phash_iter : public sc_phash_base_iter { 238public: 239 sc_phash_iter(sc_phash<K,C>* t) : sc_phash_base_iter(t) { } 240 sc_phash_iter(sc_phash<K,C>& t) : sc_phash_base_iter(t) { } 241 ~sc_phash_iter() { } 242 243 void reset(sc_phash<K,C>* t) { sc_phash_base_iter::reset(t); } 244 void reset(sc_phash<K,C>& t) { sc_phash_base_iter::reset(t); } 245 246 K key() const { return (K) sc_phash_base_iter::key(); } 247 C contents() const { return (C) sc_phash_base_iter::contents(); } 248 C set_contents(C c) 249 { 250 return (C) sc_phash_base_iter::set_contents((void*) c); 251 } 252}; 253 254 255 256 257 258template< class K, class C > 259class sc_pdhash : public sc_phash_base { 260 friend class sc_pdhash_iter<K,C>; 261 262private: 263 void* (*kdup)(const void*); //eliminated braces around void* -- Amit 264 void (*kfree)(void*); 265 266public: 267 typedef sc_pdhash_iter<K,C> iterator; 268 sc_pdhash( C def = (C) 0, 269 int size = PHASH_DEFAULT_INIT_TABLE_SIZE, 270 int density = PHASH_DEFAULT_MAX_DENSITY, 271 double grow = PHASH_DEFAULT_GROW_FACTOR, 272 bool reorder = PHASH_DEFAULT_REORDER_FLAG, 273 hash_fn_t hash_fn = (hash_fn_t) 0, // defaults added -- 274 cmpr_fn_t cmpr_fn = (cmpr_fn_t) 0, // Amit 275 void* (*kdup_fn)(const void*) = 0, 276 void (*kfree_fn)(void*) = 0 ) 277 : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) 278 { 279 kdup = kdup_fn; 280 kfree = kfree_fn; 281 } 282 ~sc_pdhash() 283 { 284 erase(); 285 } 286 void erase() 287 { 288 sc_phash_base::erase(kfree); 289 } 290 void copy(const sc_pdhash<K,C>& b) { sc_phash_base::copy(b, kdup, kfree); } 291 int insert(K k, C c) { return sc_phash_base::insert((void*) k, (void*) c, kdup); } 292 int insert(K k) { return sc_phash_base::insert((void*) k, default_value, kdup); } 293 int insert_if_not_exists(K k, C c) 294 { 295 return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, kdup); 296 } 297 int insert_if_not_exists(K k) 298 { 299 return sc_phash_base::insert_if_not_exists((void*) k, default_value, kdup); 300 } 301 int remove(K k) { return sc_phash_base::remove((const void*) k, kfree); } 302 int remove(K k, K* pk, C* pc) 303 { 304 return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); 305 } 306 int remove_by_contents(C c) 307 { 308 return sc_phash_base::remove_by_contents((const void*) c, kfree); 309 } 310 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) 311 { 312 return sc_phash_base::remove_by_contents(predicate, arg, kfree); 313 } 314 int lookup(K k, C* pc) const 315 { 316 return sc_phash_base::lookup((const void*) k, (void**) pc); 317 } 318 bool contains(K k) const 319 { 320 return sc_phash_base::contains((const void*) k); 321 } 322 C operator[](K k) const 323 { 324 return (C) sc_phash_base::operator[]((const void*) k); 325 } 326}; 327 328template< class K, class C > 329class sc_pdhash_iter : public sc_phash_base_iter { 330public: 331 sc_pdhash_iter(sc_pdhash<K,C>* t) : sc_phash_base_iter(t) { } 332 sc_pdhash_iter(sc_pdhash<K,C>& t) : sc_phash_base_iter(t) { } 333 ~sc_pdhash_iter() { } 334 335 void reset(sc_pdhash<K,C>* t) { sc_phash_base_iter::reset(t); } 336 void reset(sc_pdhash<K,C>& t) { sc_phash_base_iter::reset(t); } 337 338 void remove() { sc_phash_base_iter::remove(((sc_pdhash<K,C>*) table)->kfree); } 339 K key() const { return (K) sc_phash_base_iter::key(); } 340 C contents() const { return (C) sc_phash_base_iter::contents(); } 341 C set_contents(C c) 342 { 343 return (C) sc_phash_base_iter::set_contents((void*) c); 344 } 345}; 346 347extern int sc_strhash_cmp( const void*, const void* ); 348extern void sc_strhash_kfree(void*); 349extern void* sc_strhash_kdup(const void*); 350 351template< class C > // template class decl. 352class sc_strhash_iter; // --Amit 353 354template< class C > 355class sc_strhash : public sc_phash_base { 356 friend class sc_strhash_iter<C>; 357 358public: 359 typedef sc_strhash_iter<C> iterator; 360 361 sc_strhash( C def = (C) 0, 362 int size = PHASH_DEFAULT_INIT_TABLE_SIZE, 363 int density = PHASH_DEFAULT_MAX_DENSITY, 364 double grow = PHASH_DEFAULT_GROW_FACTOR, 365 bool reorder = PHASH_DEFAULT_REORDER_FLAG, 366 unsigned (*hash_fn)(const void*) = default_str_hash_fn, 367 int (*cmpr_fn)(const void*, const void*) = sc_strhash_cmp ) 368 : sc_phash_base((void*) def, size, density, grow, reorder, hash_fn, cmpr_fn) 369 { 370 371 } 372 ~sc_strhash() 373 { 374 erase(); 375 } 376 377 void erase() { sc_phash_base::erase(sc_strhash_kfree); } 378 void copy(const sc_strhash<C>* b) { sc_phash_base::copy(*b, sc_strhash_kdup, sc_strhash_kfree); } 379 void copy(const sc_strhash<C>& b) { sc_phash_base::copy(b, sc_strhash_kdup, sc_strhash_kfree); } 380 381 int insert(char* k, C c) { return sc_phash_base::insert((void*) k, (void*) c, sc_strhash_kdup); } 382 int insert(char* k) { return sc_phash_base::insert((void*) k, default_value, sc_strhash_kdup); } 383 int insert_if_not_exists(char* k, C c) 384 { 385 return sc_phash_base::insert_if_not_exists((void*) k, (void*) c, sc_strhash_kdup); 386 } 387 int insert_if_not_exists(char* k) 388 { 389 return sc_phash_base::insert_if_not_exists((void*) k, default_value, sc_strhash_kdup); 390 } 391 int remove(const char* k) { return sc_phash_base::remove((const void*) k, sc_strhash_kfree); } 392 int remove(const char* k, char** pk, C* pc) 393 { 394 return sc_phash_base::remove((const void*) k, (void**) pk, (void**) pc); 395 } 396 int remove_by_contents(C c) 397 { 398 return sc_phash_base::remove_by_contents((const void*) c, sc_strhash_kfree); 399 } 400 int remove_by_contents(bool (*predicate)(const void*, void*), void* arg) 401 { 402 return sc_phash_base::remove_by_contents(predicate, arg, sc_strhash_kfree); 403 } 404 int lookup(const char* k, C* pc) const 405 { 406 return sc_phash_base::lookup((const void*) k, (void** )pc); 407 } 408 bool contains(const char* k) const 409 { 410 return sc_phash_base::contains((const void*) k); 411 } 412 C operator[](const char* k) const 413 { 414 return (C) sc_phash_base::operator[]((const void*) k); 415 } 416}; 417 418template<class C> 419class sc_strhash_iter : public sc_phash_base_iter { 420public: 421 sc_strhash_iter ( sc_strhash<C>* t ) : sc_phash_base_iter(t) { } 422 sc_strhash_iter ( sc_strhash<C>& t ) : sc_phash_base_iter(t) { } 423 ~sc_strhash_iter() { } 424 425 void reset ( sc_strhash<C>* t ) { sc_phash_base_iter::reset(t); } 426 void reset ( sc_strhash<C>& t ) { sc_phash_base_iter::reset(t); } 427 428 void remove() { sc_phash_base_iter::remove(sc_strhash_kfree); } 429 const char* key() { return (const char*) sc_phash_base_iter::key(); } 430 C contents() { return (C) sc_phash_base_iter::contents(); } 431 C set_contents(C c) 432 { 433 return (C) sc_phash_base_iter::set_contents((void*) c); 434 } 435}; 436 437} // namespace sc_core 438 439// $Log: sc_hash.h,v $ 440// Revision 1.5 2011/08/29 18:04:32 acg 441// Philipp A. Hartmann: miscellaneous clean ups. 442// 443// Revision 1.4 2011/08/26 20:46:16 acg 444// Andy Goodrich: moved the modification log to the end of the file to 445// eliminate source line number skew when check-ins are done. 446// 447// Revision 1.3 2011/08/24 22:05:56 acg 448// Torsten Maehne: initialization changes to remove warnings. 449// 450// Revision 1.2 2011/02/18 20:38:43 acg 451// Andy Goodrich: Updated Copyright notice. 452// 453// Revision 1.1.1.1 2006/12/15 20:20:06 acg 454// SystemC 2.3 455// 456// Revision 1.3 2006/01/13 18:53:10 acg 457// Andy Goodrich: Added $Log command so that CVS comments are reproduced in 458// the source. 459 460#endif 461