Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 //-*-c++-*- 00037 // ==================================================================== 00038 // ==================================================================== 00039 // 00040 // 00041 // Revision history: 00042 // 07-Dec-95 - Merged USER_HASH_TABLE support. 00043 // 00044 // Description: 00045 // 00046 // This file contains templates for open hash tables. 00047 // 00048 // ==================================================================== 00049 // 00050 // (template...) class HASH_TABLE 00051 // 00052 // The first implementation maps SIG_TYPE keys into DATA_TYPE *data. 00053 // A typical instantiation would be INT for SIG_TYPE and void * for 00054 // DATA_TYPE. This implementation has the following key attributes: 00055 // 00056 // 1) The size of the hash table is determined at constructor time. 00057 // 00058 // 2) The hash table elements are lists of objects. 00059 // 00060 // 3) The objects in the table's lists are pairs consisting of a 00061 // signature (key) and a data element to which the key is mapped. 00062 // 00063 // 4) The hash function is a built in function of the signature. 00064 // Therefore, for example, it will be the pointer value for 00065 // a string key, and will produce different entries for distinct 00066 // pointers to the same character string. 00067 // 00068 // template <class SIG_TYPE, class DATA_TYPE> class HASH_TABLE 00069 // 00070 // An open hash table. This table maps SIG_TYPE signatures 00071 // into DATA_TYPE data. 00072 // 00073 // HASH_TABLE(const UINT num_elements, MEM_POOL *pool) 00074 // 00075 // Create a new hash table with num_elements elements. 00076 // Store the table in pool. 00077 // 00078 // void Enter(SIG_TYPE signature, DATA_TYPE data) 00079 // 00080 // Enter into the table the pair (signature, data) 00081 // This routine does not check for duplicates. 00082 // 00083 // void Enter_If_Unique(SIG_TYPE signature, DATA_TYPE data) 00084 // 00085 // Enter the pair into the table if signature is not 00086 // already in the table 00087 // 00088 // DATA_TYPE Find(SIG_TYPE signature) const 00089 // 00090 // Return the data if it is in the table, NULL otherwise. 00091 // 00092 // void Remove(SIG_TYPE signature) 00093 // 00094 // If it's in the table, remove it 00095 // 00096 // UINT Num_Entries() const 00097 // Return the number of entries in the table. 00098 // This is different from Num_Elements. 00099 // 00100 // ~HASH_TABLE() 00101 // 00102 // template <class SIG_TYPE, class DATA_TYPE> HASH_TABLE_ITER 00103 // 00104 // HASH_TABLE_ITER(const HASH_TABLE*) 00105 // BOOL Step(SIG_TYPE*, DATA_TYPE*) 00106 // 00107 // Usage: 00108 // HASH_TABLE_ITER it(hashtable); 00109 // while (it.Step(&sig, &data)) 00110 // ... 00111 // 00112 // ==================================================================== 00113 // 00114 // (template...) class USER_HASH_TABLE 00115 // 00116 // The second implementation maps KEY_TYPE keys into DATA_TYPE *data. 00117 // It is very similar to HASH_TABLE, but allows the user to supply a 00118 // hash function and a key equality function. 00119 // 00120 // A typical instantiation would be char * for KEY_TYPE and void * for 00121 // DATA_TYPE. This implementation has the following key attributes: 00122 // 00123 // 1) The size of the hash table is determined at constructor time. 00124 // 00125 // 2) The hash table elements are lists of objects. 00126 // 00127 // 3) The objects in the table's lists are pairs consisting of a 00128 // signature (key) and a data element to which the key is mapped. 00129 // 00130 // 4) The hash function is provided by the user as a function object 00131 // HASH_FUNC on the KEY_TYPE, and equivalence between keys is 00132 // also provided by a user function object KEY_EQ. We supply 00133 // reasonable hash and equality functions for character strings 00134 // below. 00135 // 00136 // typedef ... HASH; 00137 // This type must be the result type of the user hash function. 00138 // 00139 // template < class KEY_TYPE, class DATA_TYPE, 00140 // class HASH_FUNC, class KEY_EQ > 00141 // class USER_HASH_TABLE 00142 // 00143 // An open hash table. This table maps KEY_TYPE 00144 // keys into DATA_TYPE data. HASH_FUNC must map 00145 // KEY_TYPE objects into an HASH hash value, and KEY_EQ 00146 // must compare two KEY_TYPE objects for equality and 00147 // return a BOOL result. 00148 // 00149 // USER_HASH_TABLE ( const UINT32 num_elements, MEM_POOL *pool ) 00150 // 00151 // Create a new hash table with num_elements elements. 00152 // Store the table in pool. It may later be resized. 00153 // 00154 // void Enter ( KEY_TYPE key, DATA_TYPE data ) 00155 // 00156 // Enter into the table the pair (key, data) 00157 // This routine does not check for duplicates. 00158 // 00159 // void Enter_If_Unique ( KEY_TYPE key, DATA_TYPE data ) 00160 // 00161 // Enter the pair into the table if key is not 00162 // already in the table 00163 // 00164 // DATA_TYPE Find ( KEY_TYPE key ) const 00165 // 00166 // Return the data if it is in the table, NULL otherwise. 00167 // 00168 // UINT Num_Entries() const 00169 // Return the number of entries in the table. 00170 // This is different from Num_Elements. 00171 // 00172 // ~HASH_TABLE() 00173 // 00174 // template < class KEY_TYPE, class DATA_TYPE, 00175 // class HASH_FUNC, class KEY_EQ > 00176 // USER_HASH_TABLE_ITER 00177 // 00178 // USER_HASH_TABLE_ITER ( const USER_HASH_TABLE* ) 00179 // BOOL Step ( KEY_TYPE*, DATA_TYPE* ) 00180 // 00181 // Usage: 00182 // USER_HASH_TABLE_ITER it(hashtable); 00183 // while (it.Step(&key, &data)) 00184 // ... 00185 // 00186 // ==================================================================== 00187 // 00188 // HASH String_Hash ( const char *k ); 00189 // This function object may be used as the HASH_FUNC parameter 00190 // for USER_HASH_TABLE instances with string keys. 00191 // 00192 // BOOL String_Compare ( const char *s, const char *t ); 00193 // This function object may be used as the KEY_EQ parameter for 00194 // USER_HASH_TABLE instances with string keys. 00195 // 00196 // ==================================================================== 00197 // 00198 // NOTE: The bodies for the definitions in this file are split between 00199 // cxx_hash.cxx (template bodies) and cxx_hash_util.cxx (non-template 00200 // bodies). 00201 // 00202 // ==================================================================== 00203 // ==================================================================== 00204 00205 #ifndef cxx_hash_INCLUDED 00206 #define cxx_hash_INCLUDED "cxx_hash.h" 00207 00208 #ifdef _KEEP_RCS_ID 00209 #endif /* _KEEP_RCS_ID */ 00210 00211 #ifndef CXX_MEMORY_INCLUDED 00212 #include "cxx_memory.h" 00213 #endif 00214 #include "erglob.h" 00215 00216 // ==================================================================== 00217 // ==================================================================== 00218 // 00219 // HASH_ELEMENT 00220 // 00221 // For both hash map implementations, the main hash table contains 00222 // lists of these objects. 00223 // 00224 // This is public, but no one should touch this except HASH_TABLE, 00225 // HASH_TABLE_ITER, USER_HASH_TABLE, and USER_HASH_TABLE_ITER. 00226 // I would use friend functions, but they don't seem to work with 00227 // templates. 00228 // 00229 // ==================================================================== 00230 // ==================================================================== 00231 00232 template <class SIG_TYPE, class DATA_TYPE> 00233 class HASH_ELEMENT 00234 { 00235 public: 00236 DATA_TYPE _data; 00237 SIG_TYPE _signature; 00238 HASH_ELEMENT *_next; 00239 00240 // create a new element 00241 HASH_ELEMENT(const SIG_TYPE& signature, const DATA_TYPE& data) : 00242 _signature(signature), _data(data), _next(NULL) {} 00243 void Add_To_List(HASH_ELEMENT *e) { e->_next = _next; _next = e; } 00244 }; 00245 00246 // ==================================================================== 00247 // ==================================================================== 00248 // 00249 // HASH_TABLE 00250 // 00251 // This is a basic hash map, with a built-in hash function. 00252 // 00253 // ==================================================================== 00254 // ==================================================================== 00255 00256 template <class SIG_TYPE, class DATA_TYPE> 00257 class HASH_TABLE { 00258 private: 00259 MEM_POOL *_pool; 00260 HASH_ELEMENT<SIG_TYPE,DATA_TYPE> * *_data; // an array of HASH_ELEMENT * 00261 UINT _num_elements; 00262 UINT _num_entries; 00263 public: 00264 HASH_TABLE<SIG_TYPE,DATA_TYPE>(UINT num_elements, MEM_POOL *pool); 00265 UINT Num_Elements() const { return _num_elements; }; 00266 UINT Num_Entries() const { return _num_entries; }; 00267 HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *Data(UINT i) const { return _data[i]; }; 00268 00269 void Enter(SIG_TYPE signature,DATA_TYPE data) { 00270 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> THIS_HASH_ELEMENT; 00271 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00272 HASH_ELEMENTP element = 00273 CXX_NEW(THIS_HASH_ELEMENT(signature,data),_pool); 00274 UINT location = abs((INT)(INTPS)signature) % _num_elements; 00275 if (_data[location]) { // some thing is there 00276 _data[location]->Add_To_List(element); 00277 } else { 00278 _data[location] = element; 00279 } 00280 _num_entries++; 00281 } 00282 00283 void Enter_If_Unique(SIG_TYPE signature,DATA_TYPE data); 00284 DATA_TYPE Find(SIG_TYPE signature) const; 00285 void Remove(SIG_TYPE signature); 00286 00287 // Destructor -- remove all entries and the pointer array: 00288 ~HASH_TABLE() { 00289 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00290 for (UINT loc = 0; loc < _num_elements; loc++) { 00291 HASH_ELEMENTP element = _data[loc]; 00292 HASH_ELEMENTP next_element; 00293 while (element) { 00294 next_element = element->_next; 00295 CXX_DELETE(element, _pool); 00296 element = next_element; 00297 } 00298 } 00299 CXX_DELETE_ARRAY(_data, _pool); 00300 }; 00301 00302 }; 00303 00304 template <class SIG_TYPE, class DATA_TYPE> 00305 class HASH_TABLE_ITER { 00306 private: 00307 INT _loc; 00308 HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *_he; 00309 const HASH_TABLE<SIG_TYPE,DATA_TYPE> *_hash; 00310 public: 00311 BOOL Step(SIG_TYPE* sig, DATA_TYPE* data); // TRUE of ok 00312 HASH_TABLE_ITER(const HASH_TABLE<SIG_TYPE,DATA_TYPE> * h) : 00313 _hash(h), _loc(-1), _he(NULL) {} 00314 ~HASH_TABLE_ITER() {} 00315 }; 00316 00317 // ==================================================================== 00318 // ==================================================================== 00319 // 00320 // Support for USER_HASH_TABLE 00321 // 00322 // Define the required result type of the hash function, and provide 00323 // basic string hash and equality function objects. 00324 // 00325 // ==================================================================== 00326 // ==================================================================== 00327 00328 // Hash value typedef: 00329 typedef UINT32 HASH; 00330 00331 // String hash function: 00332 struct String_Hash 00333 { 00334 HASH operator() ( const char * k ) const; 00335 }; 00336 00337 // String equality function: 00338 struct String_Equal 00339 { 00340 BOOL operator() ( const char *a, const char *b ) const 00341 { return ! strcmp ( a, b ); } 00342 }; 00343 00344 // ==================================================================== 00345 // ==================================================================== 00346 // 00347 // USER_HASH_TABLE 00348 // 00349 // This is a hash map, very similar to HASH_TABLE, but allowing the 00350 // user to specify the hash function and key equality as function 00351 // objects. 00352 // 00353 // ==================================================================== 00354 // ==================================================================== 00355 00356 // The template parameter list is long and unwieldy: 00357 #define TEMPLATE_USER_HASH_TABLE template \ 00358 < class KEY_TYPE, class DATA_TYPE, class HASH_FUNC, class KEY_EQ > 00359 #define CLASS_USER_HASH_TABLE \ 00360 USER_HASH_TABLE < KEY_TYPE, DATA_TYPE, HASH_FUNC, KEY_EQ > 00361 00362 TEMPLATE_USER_HASH_TABLE 00363 class USER_HASH_TABLE { 00364 private: 00365 MEM_POOL *_pool; 00366 HASH_ELEMENT<KEY_TYPE,DATA_TYPE> * *_data; // array of HASH_ELEMENT* 00367 UINT32 _num_elements; 00368 UINT _num_entries; 00369 HASH_FUNC _hash; 00370 KEY_EQ _equal; 00371 00372 public: 00373 // Constructor -- Build a map in 'pool' with 'num_elements' slots: 00374 USER_HASH_TABLE ( UINT32 num_elements, MEM_POOL *pool ); 00375 00376 // Tracing -- only valid if KEY_TYPE is char*: 00377 void Print ( FILE *f ); 00378 00379 // Field access: 00380 UINT32 Num_Elements ( void ) const { return _num_elements; }; 00381 UINT Num_Entries( void ) const { return _num_entries; }; 00382 HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *Data ( UINT32 i) const 00383 { return _data[i]; } 00384 00385 // Enter a new element without checking for duplication: 00386 void Enter ( KEY_TYPE key, DATA_TYPE data ) { 00387 typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> THIS_HASH_ELEMENT; 00388 typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00389 HASH_ELEMENTP element = 00390 CXX_NEW ( THIS_HASH_ELEMENT(key,data), _pool ); 00391 UINT32 location = _hash(key) % _num_elements; 00392 00393 element->_next = _data[location]; 00394 _data[location] = element; 00395 _num_entries++; 00396 } 00397 00398 // Enter a new element only if the given key is not already mapped: 00399 void Enter_If_Unique ( KEY_TYPE key, DATA_TYPE data ); 00400 00401 // Find the given key in the map: 00402 DATA_TYPE Find(KEY_TYPE key) const; 00403 00404 // Destructor -- remove all entries and the pointer array: 00405 ~USER_HASH_TABLE() { 00406 typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00407 for (UINT loc = 0; loc < _num_elements; loc++) { 00408 HASH_ELEMENTP element = _data[loc]; 00409 HASH_ELEMENTP next_element; 00410 while (element) { 00411 next_element = element->_next; 00412 CXX_DELETE(element, _pool); 00413 element = next_element; 00414 } 00415 } 00416 CXX_DELETE_ARRAY(_data, _pool); 00417 }; 00418 }; 00419 00420 TEMPLATE_USER_HASH_TABLE 00421 class USER_HASH_TABLE_ITER { 00422 private: 00423 INT _loc; 00424 HASH_ELEMENT<KEY_TYPE,DATA_TYPE> *_he; 00425 const USER_HASH_TABLE < KEY_TYPE, DATA_TYPE, HASH_FUNC, KEY_EQ > *_hash; 00426 00427 public: 00428 BOOL Step ( KEY_TYPE* key, DATA_TYPE* data ); // TRUE of ok 00429 USER_HASH_TABLE_ITER ( 00430 const USER_HASH_TABLE < KEY_TYPE, DATA_TYPE, HASH_FUNC, KEY_EQ > * h ) : 00431 _hash(h), _loc(-1), _he(NULL) {} 00432 ~USER_HASH_TABLE_ITER ( void ) {} 00433 }; 00434 00435 // Implementation stuff follows. This was taken from cxx_hash.cxx, 00436 // since g++ (rightly) doesn't do the "implicit .cxx file inclusion" 00437 // thing. 00438 00439 // ==================================================================== 00440 // ==================================================================== 00441 // 00442 // HASH_TABLE 00443 // 00444 // This is a simple hash map, with the following attributes: 00445 // 00446 // 1) The size of the hash table is determined at constructor time. 00447 // 00448 // 2) The hash table elements are lists of objects. 00449 // 00450 // 3) The objects in the table's lists are pairs consisting of a 00451 // signature (key) and a data element to which the key is mapped. 00452 // 00453 // 4) The hash function is built in as the signature modulo the table 00454 // size. Therefore, for example, it will be the pointer value for 00455 // a string key, and will produce different entries for distinct 00456 // pointers to the same character string. 00457 // 00458 // ==================================================================== 00459 // ==================================================================== 00460 00461 template <class SIG_TYPE, class DATA_TYPE> 00462 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: HASH_TABLE ( 00463 UINT num_elements, 00464 MEM_POOL *pool ) 00465 { 00466 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00467 _pool = pool; 00468 _num_elements = num_elements; 00469 _num_entries = 0; 00470 _data = CXX_NEW_ARRAY(HASH_ELEMENTP ,num_elements,pool); 00471 for (INT i=0; i<num_elements; i++) { 00472 _data[i] = (HASH_ELEMENTP) 0; 00473 } 00474 } 00475 00476 template <class SIG_TYPE, class DATA_TYPE> 00477 void 00478 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Enter_If_Unique(SIG_TYPE signature, 00479 DATA_TYPE data) 00480 { 00481 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> THIS_HASH_ELEMENT; 00482 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00483 HASH_ELEMENTP element = 00484 CXX_NEW(THIS_HASH_ELEMENT(signature,data),_pool); 00485 UINT location = abs((INT)(INTPS)signature) % _num_elements; 00486 00487 if (_data[location]) { // something is there 00488 HASH_ELEMENTP iter = _data[location]; 00489 for (; iter != NULL ; iter = iter->_next) { 00490 if (iter->_signature == signature) { 00491 return; // not unique 00492 } 00493 } 00494 _data[location]->Add_To_List(element); 00495 } else { 00496 _data[location] = element; 00497 } 00498 _num_entries++; 00499 } 00500 00501 template <class SIG_TYPE, class DATA_TYPE> 00502 DATA_TYPE 00503 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Find ( 00504 SIG_TYPE signature ) const 00505 { 00506 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00507 HASH_ELEMENTP hash_element = _data[abs((INT)(INTPS)signature) % _num_elements]; 00508 00509 for (; hash_element != NULL; hash_element = hash_element->_next) { 00510 if (hash_element->_signature == signature) { 00511 return(hash_element->_data); 00512 } 00513 } 00514 return((DATA_TYPE)0); 00515 } 00516 00517 template <class SIG_TYPE, class DATA_TYPE> 00518 void HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Remove ( 00519 SIG_TYPE signature ) 00520 { 00521 typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP; 00522 HASH_ELEMENTP hash_element = _data[abs((INT)signature) % _num_elements]; 00523 00524 if (hash_element->_signature == signature) { 00525 _data[abs((INT)(INTPS)signature) % _num_elements] = hash_element->_next; 00526 CXX_DELETE(hash_element,_pool); 00527 _num_entries--; 00528 return; 00529 } 00530 00531 HASH_ELEMENTP prev = hash_element; 00532 for (hash_element = hash_element->_next; hash_element; 00533 hash_element = hash_element->_next) { 00534 if (hash_element->_signature == signature) { 00535 prev->_next = hash_element->_next; 00536 CXX_DELETE(hash_element,_pool); 00537 _num_entries--; 00538 return; 00539 } 00540 prev = hash_element; 00541 } 00542 } 00543 00544 template <class SIG_TYPE, class DATA_TYPE> 00545 BOOL 00546 HASH_TABLE_ITER<SIG_TYPE,DATA_TYPE> :: Step ( 00547 SIG_TYPE* sig, 00548 DATA_TYPE* data ) 00549 { 00550 if (_he && _he->_next) { 00551 _he = _he->_next; 00552 *sig = _he->_signature; 00553 *data = _he->_data; 00554 return TRUE; 00555 } 00556 00557 for (_loc++; _loc < _hash->Num_Elements(); _loc++) { 00558 if (_hash->Data(_loc)) { 00559 _he = _hash->Data(_loc); 00560 *sig = _he->_signature; 00561 *data = _he->_data; 00562 return TRUE; 00563 } 00564 } 00565 00566 return FALSE; 00567 } 00568 00569 // ==================================================================== 00570 // ==================================================================== 00571 // 00572 // USER_HASH_TABLE 00573 // 00574 // This is a hash map, very similar to HASH_TABLE, with the following 00575 // attributes (only #4 differs from HASH_TABLE): 00576 // 00577 // 1) The size of the hash table is determined at constructor time. 00578 // 00579 // 2) The hash table elements are lists of objects. 00580 // 00581 // 3) The objects in the table's lists are pairs consisting of a 00582 // signature (key) and a data element to which the key is mapped. 00583 // 00584 // 4) The hash function is provided by the user as a function object 00585 // HASH_FUNC on the KEY_TYPE, and equivalence between keys is 00586 // also provided by a user function object KEY_EQ. 00587 // 00588 // ==================================================================== 00589 // ==================================================================== 00590 00591 TEMPLATE_USER_HASH_TABLE 00592 CLASS_USER_HASH_TABLE :: USER_HASH_TABLE 00593 ( UINT32 num_elements, MEM_POOL *pool ) 00594 { 00595 typedef HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *pHASH_ELEMENT; 00596 00597 _pool = pool; 00598 _num_elements = num_elements; 00599 _num_entries = 0; 00600 _data = CXX_NEW_ARRAY ( pHASH_ELEMENT, num_elements, pool ); 00601 if ( _data == NULL ) { 00602 ErrMsg ( EC_No_Mem, "USER_HASH_TABLE::USER_HASH_TABLE" ); 00603 } 00604 for ( INT i=0; i<num_elements; i++ ) { 00605 _data[i] = (pHASH_ELEMENT) NULL; 00606 } 00607 } 00608 00609 TEMPLATE_USER_HASH_TABLE 00610 void 00611 CLASS_USER_HASH_TABLE :: Print ( FILE *f ) 00612 { 00613 HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *elt; 00614 00615 for ( INT32 i = 0; i < _num_elements; i++ ) { 00616 if ( _data[i] != NULL ) { 00617 fprintf ( f, "%2d:", i ); 00618 elt = _data[i]; 00619 while ( elt != NULL ) { 00620 fprintf ( f, " k%2d:%s:d%d:n0x%06lx", 00621 _hash(elt->_signature) % _num_elements, 00622 elt->_signature, elt->_data, elt->_next ); 00623 elt = elt->_next; 00624 } 00625 fprintf ( f, "\n" ); 00626 } 00627 } 00628 } 00629 00630 TEMPLATE_USER_HASH_TABLE 00631 void 00632 CLASS_USER_HASH_TABLE :: Enter_If_Unique(KEY_TYPE key, DATA_TYPE data) 00633 { 00634 typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> THIS_HASH_ELEMENT; 00635 typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> *pHASH_ELEMENT; 00636 pHASH_ELEMENT element = 00637 CXX_NEW ( THIS_HASH_ELEMENT(key,data), _pool ); 00638 UINT32 location = _hash ( key ) % _num_elements; 00639 00640 if ( element == NULL ) { 00641 ErrMsg ( EC_No_Mem, "USER_HASH_TABLE::Enter_If_Unique" ); 00642 } 00643 00644 if ( _data[location] ) { // something is there 00645 pHASH_ELEMENT iter = _data[location]; 00646 00647 for ( ; iter != NULL ; iter = iter->_next ) { 00648 if ( _equal ( iter->_signature, key ) ) { 00649 return; // not unique 00650 } 00651 } 00652 element->_next = _data[location]; 00653 } 00654 _data[location] = element; 00655 _num_entries++; 00656 } 00657 00658 TEMPLATE_USER_HASH_TABLE 00659 DATA_TYPE 00660 CLASS_USER_HASH_TABLE :: Find ( KEY_TYPE key ) const 00661 { 00662 typedef HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *pHASH_ELEMENT; 00663 HASH hash = _hash(key) % _num_elements; 00664 pHASH_ELEMENT hash_element = _data[hash]; 00665 00666 // fprintf ( TFile, "Find: 0x%08lx %2d 0x%08lx %s\n", 00667 // key, hash, hash_element, key ); 00668 // fflush ( TFile ); 00669 00670 for ( ; hash_element != NULL; hash_element = hash_element->_next ) { 00671 if ( _equal ( hash_element->_signature, key ) ) { 00672 return ( hash_element->_data ); 00673 } 00674 } 00675 00676 return((DATA_TYPE)0); 00677 } 00678 00679 TEMPLATE_USER_HASH_TABLE 00680 BOOL 00681 USER_HASH_TABLE_ITER < KEY_TYPE, DATA_TYPE, HASH_FUNC, KEY_EQ > :: Step 00682 ( KEY_TYPE* key, DATA_TYPE* data ) 00683 { 00684 if ( _he && _he->_next ) { 00685 _he = _he->_next; 00686 *key = _he->_signature; 00687 *data = _he->_data; 00688 return TRUE; 00689 } 00690 00691 for ( _loc++; _loc < _hash->Num_Elements(); _loc++ ) { 00692 if ( _hash->Data(_loc) ) { 00693 _he = _hash->Data(_loc); 00694 *key = _he->_signature; 00695 *data = _he->_data; 00696 return TRUE; 00697 } 00698 } 00699 00700 return FALSE; 00701 } 00702 #endif /* cxx_hash_INCLUDED */ 00703