Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cxx_hash.cxx
Go to the documentation of this file.
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 version from IPA
00043 //
00044 // Description:
00045 //
00046 // Template member function bodies for template hash map
00047 // implementations.
00048 //
00049 // ====================================================================
00050 // ====================================================================
00051 
00052 #ifdef _KEEP_RCS_ID
00053 #define cxx_hash_CXX      "cxx_hash.cxx"
00054 #endif /* _KEEP_RCS_ID */
00055 
00056 #include "erglob.h"
00057 #include "cxx_hash.h"
00058 
00059 // ====================================================================
00060 // ====================================================================
00061 //
00062 // HASH_TABLE
00063 //
00064 // This is a simple hash map, with the following attributes:
00065 //
00066 //  1)  The size of the hash table is determined at constructor time.
00067 //
00068 //  2)  The hash table elements are lists of objects.
00069 //
00070 //  3)  The objects in the table's lists are pairs consisting of a
00071 //      signature (key) and a data element to which the key is mapped.
00072 //
00073 //  4)  The hash function is built in as the signature modulo the table
00074 //      size.  Therefore, for example, it will be the pointer value for
00075 //      a string key, and will produce different entries for distinct
00076 //      pointers to the same character string.
00077 //
00078 // ====================================================================
00079 // ====================================================================
00080 
00081 #if 0
00082 
00083 template <class SIG_TYPE, class DATA_TYPE>
00084 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: HASH_TABLE (
00085   UINT num_elements,
00086   MEM_POOL *pool )
00087 {
00088   typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP;
00089   _pool = pool;
00090   _num_elements = num_elements;
00091   _num_entries = 0;
00092   _data = CXX_NEW_ARRAY(HASH_ELEMENTP ,num_elements,pool);
00093   for (INT i=0; i<num_elements; i++) {
00094     _data[i] = (HASH_ELEMENTP) 0;
00095   }
00096 }
00097 
00098 template <class SIG_TYPE, class DATA_TYPE>
00099 void
00100 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Enter_If_Unique(SIG_TYPE signature, 
00101                                                   DATA_TYPE data)
00102 { 
00103   typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> THIS_HASH_ELEMENT;
00104   typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP;
00105   HASH_ELEMENTP element = 
00106     CXX_NEW(THIS_HASH_ELEMENT(signature,data),_pool);
00107   UINT location = abs((INT)signature) % _num_elements;
00108 
00109   if (_data[location]) { // something is there
00110     HASH_ELEMENTP iter = _data[location];
00111     for (; iter != NULL ; iter = iter->_next) {
00112       if (iter->_signature == signature) {
00113          return; // not unique
00114       }
00115     }
00116     _data[location]->Add_To_List(element);
00117   } else {
00118     _data[location] = element;
00119   }
00120   _num_entries++;
00121 }
00122 
00123 template <class SIG_TYPE, class DATA_TYPE>
00124 DATA_TYPE
00125 HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Find (
00126   SIG_TYPE signature ) const
00127 {
00128   typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP;
00129   HASH_ELEMENTP hash_element = _data[abs((INT)signature) % _num_elements];
00130 
00131   for (; hash_element != NULL; hash_element = hash_element->_next) {
00132     if (hash_element->_signature == signature) {
00133       return(hash_element->_data);
00134     }
00135   }
00136   return((DATA_TYPE)NULL);
00137 }
00138 
00139 template <class SIG_TYPE, class DATA_TYPE>
00140 void HASH_TABLE<SIG_TYPE,DATA_TYPE> :: Remove (
00141   SIG_TYPE signature ) 
00142 {
00143   typedef HASH_ELEMENT<SIG_TYPE,DATA_TYPE> *HASH_ELEMENTP;
00144   HASH_ELEMENTP hash_element = _data[abs((INT)signature) % _num_elements];
00145 
00146   if (hash_element->_signature == signature) {
00147     _data[abs((INT)signature) % _num_elements] = hash_element->_next;
00148     CXX_DELETE(hash_element,_pool);
00149     _num_entries--;
00150     return;
00151   }
00152 
00153   HASH_ELEMENTP prev = hash_element;
00154   for (hash_element = hash_element->_next; hash_element; 
00155                                 hash_element = hash_element->_next) {
00156     if (hash_element->_signature == signature) {
00157       prev->_next = hash_element->_next;
00158       CXX_DELETE(hash_element,_pool);
00159       _num_entries--;
00160       return;
00161     }
00162     prev = hash_element;
00163   }
00164 }
00165 
00166 template <class SIG_TYPE, class DATA_TYPE>
00167 BOOL
00168 HASH_TABLE_ITER<SIG_TYPE,DATA_TYPE> :: Step (
00169   SIG_TYPE* sig,
00170   DATA_TYPE* data )
00171 {
00172   if (_he && _he->_next) {
00173     _he = _he->_next;
00174     *sig = _he->_signature;
00175     *data = _he->_data;
00176     return TRUE;
00177   }
00178     
00179   for (_loc++; _loc < _hash->Num_Elements(); _loc++) {
00180     if (_hash->Data(_loc)) {
00181       _he = _hash->Data(_loc);
00182       *sig = _he->_signature;
00183       *data = _he->_data;
00184       return TRUE;
00185     }
00186   }
00187 
00188   return FALSE;
00189 }
00190 
00191 // ====================================================================
00192 // ====================================================================
00193 //
00194 // USER_HASH_TABLE
00195 //
00196 // This is a hash map, very similar to HASH_TABLE, with the following
00197 // attributes (only #4 differs from HASH_TABLE):
00198 //
00199 //  1)  The size of the hash table is determined at constructor time.
00200 //
00201 //  2)  The hash table elements are lists of objects.
00202 //
00203 //  3)  The objects in the table's lists are pairs consisting of a
00204 //      signature (key) and a data element to which the key is mapped.
00205 //
00206 //  4)  The hash function is provided by the user as a function object
00207 //      HASH_FUNC on the KEY_TYPE, and equivalence between keys is
00208 //      also provided by a user function object KEY_EQ.
00209 //
00210 // ====================================================================
00211 // ====================================================================
00212 
00213 TEMPLATE_USER_HASH_TABLE
00214 CLASS_USER_HASH_TABLE :: USER_HASH_TABLE
00215   ( UINT32 num_elements, MEM_POOL *pool )
00216 {
00217   typedef HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *pHASH_ELEMENT;
00218 
00219   _pool = pool;
00220   _num_elements = num_elements;
00221   _num_entries = 0;
00222   _data = CXX_NEW_ARRAY ( pHASH_ELEMENT, num_elements, pool );
00223   if ( _data == NULL ) {
00224     ErrMsg ( EC_No_Mem, "USER_HASH_TABLE::USER_HASH_TABLE" );
00225   }
00226   for ( INT i=0; i<num_elements; i++ ) {
00227     _data[i] = (pHASH_ELEMENT) NULL;
00228   }
00229 }
00230 
00231 TEMPLATE_USER_HASH_TABLE
00232 void
00233 CLASS_USER_HASH_TABLE :: Print ( FILE *f )
00234 {
00235   HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *elt;
00236 
00237   for ( INT32 i = 0; i < _num_elements; i++ ) {
00238     if ( _data[i] != NULL ) {
00239       fprintf ( f, "%2d:", i );
00240       elt = _data[i];
00241       while  ( elt != NULL ) {
00242         fprintf ( f, " k%2d:%s:d%d:n0x%06lx",
00243                   _hash(elt->_signature) % _num_elements,
00244                   elt->_signature, elt->_data, elt->_next );
00245         elt = elt->_next;
00246       }
00247       fprintf ( f, "\n" );
00248     }
00249   }
00250 }
00251 
00252 TEMPLATE_USER_HASH_TABLE
00253 void
00254 CLASS_USER_HASH_TABLE :: Enter_If_Unique(KEY_TYPE key, DATA_TYPE data)
00255 { 
00256   typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> THIS_HASH_ELEMENT;
00257   typedef HASH_ELEMENT<KEY_TYPE,DATA_TYPE> *pHASH_ELEMENT;
00258   pHASH_ELEMENT element = 
00259         CXX_NEW ( THIS_HASH_ELEMENT(key,data), _pool );
00260   UINT32 location = _hash ( key ) % _num_elements;
00261 
00262   if ( element == NULL ) {
00263     ErrMsg ( EC_No_Mem, "USER_HASH_TABLE::Enter_If_Unique" );
00264   }
00265 
00266   if ( _data[location] ) { // something is there
00267     pHASH_ELEMENT iter = _data[location];
00268 
00269     for ( ; iter != NULL ; iter = iter->_next ) {
00270       if ( _equal ( iter->_signature, key ) ) {
00271         return; // not unique
00272       }
00273     }
00274     element->_next = _data[location];
00275   }
00276   _data[location] = element;
00277   _num_entries++;
00278 }
00279 
00280 TEMPLATE_USER_HASH_TABLE
00281 DATA_TYPE
00282 CLASS_USER_HASH_TABLE :: Find ( KEY_TYPE key ) const
00283 {
00284   typedef HASH_ELEMENT < KEY_TYPE, DATA_TYPE > *pHASH_ELEMENT;
00285   HASH hash = _hash(key) % _num_elements;
00286   pHASH_ELEMENT hash_element = _data[hash];
00287 
00288   // fprintf ( TFile, "Find: 0x%08lx %2d 0x%08lx %s\n",
00289   //          key, hash, hash_element, key );
00290   // fflush ( TFile );
00291 
00292   for ( ; hash_element != NULL; hash_element = hash_element->_next ) {
00293     if ( _equal ( hash_element->_signature, key ) ) {
00294       return ( hash_element->_data );
00295     }
00296   }
00297 
00298   return((DATA_TYPE)NULL);
00299 }
00300 
00301 TEMPLATE_USER_HASH_TABLE
00302 BOOL
00303 USER_HASH_TABLE_ITER < KEY_TYPE, DATA_TYPE, HASH_FUNC, KEY_EQ > :: Step
00304   ( KEY_TYPE* key, DATA_TYPE* data )
00305 {
00306   if ( _he && _he->_next ) {
00307     _he = _he->_next;
00308     *key = _he->_signature;
00309     *data = _he->_data;
00310     return TRUE;
00311   }
00312     
00313   for ( _loc++; _loc < _hash->Num_Elements(); _loc++ ) {
00314     if ( _hash->Data(_loc) ) {
00315       _he = _hash->Data(_loc);
00316       *key = _he->_signature;
00317       *data = _he->_data;
00318       return TRUE;
00319     }
00320   }
00321 
00322   return FALSE;
00323 }
00324 
00325 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines