Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
niml_htable.c
Go to the documentation of this file.00001 #include "niml_private.h"
00002
00003
00004
00005
00006
00007 #undef UINT
00008 #define UINT unsigned int
00009
00010 #undef INLINE
00011 #ifdef __GNUC__
00012 # define INLINE inline
00013 #else
00014 # define INLINE
00015 #endif
00016
00017 static int vtkill=0 ;
00018 void Htable_set_vtkill( int vt ){ vtkill = vt ; }
00019
00020
00021
00022
00023
00024 static INLINE UINT hashkey( char *str )
00025 {
00026 char *p ;
00027 unsigned int h=32003 ;
00028
00029 for( p=str ; *p != '\0' ; p++ )
00030 h = ( h << 5 ) - h + *p ;
00031
00032 #if 0
00033 h = ((h & 0xf0f0f0f0) >> 4)
00034 | ((h & 0x0f0f0f0f) << 4) ;
00035 #endif
00036
00037 return h;
00038 }
00039
00040
00041
00042
00043
00044 Htable * new_Htable( int len )
00045 {
00046 Htable *ht ;
00047
00048 if( len <= 7 ) len = 7 ;
00049 else if( len%2 == 0 ) len++ ;
00050
00051 ht = (Htable *) calloc( 1 , sizeof(Htable) ) ;
00052
00053 ht->len = len ;
00054 ht->vtab = (void ***) calloc( len , sizeof(void **) ) ;
00055 ht->ctab = (char ***) calloc( len , sizeof(char **) ) ;
00056 ht->ntab = (int *) calloc( len , sizeof(int) ) ;
00057
00058 return ht ;
00059 }
00060
00061
00062
00063
00064
00065 void destroy_Htable( Htable *ht )
00066 {
00067 int jj , kk ;
00068
00069 if( ht == NULL ) return ;
00070
00071 for( jj=0 ; jj < ht->len ; jj++ ){
00072 if( ht->vtab[jj] != NULL ){
00073 if( vtkill ){
00074 for( kk=0 ; kk < ht->ntab[jj] ; kk++ )
00075 if( ht->vtab[jj][kk] != NULL ) free(ht->vtab[jj][kk]) ;
00076 }
00077 free(ht->vtab[jj]) ;
00078 }
00079 if( ht->ctab[jj] != NULL ){
00080 for( kk=0 ; kk < ht->ntab[jj] ; kk++ )
00081 if( ht->ctab[jj][kk] != NULL ) free(ht->ctab[jj][kk]) ;
00082 free(ht->ctab[jj]) ;
00083 }
00084 }
00085 free(ht->vtab) ; free(ht->ctab) ; free(ht->ntab) ; free(ht) ;
00086 return ;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 void * findin_Htable( char *str , Htable *ht )
00096 {
00097 UINT jj ;
00098 int kk , ntab ;
00099 char *key , **ctab ;
00100 void ***vtab ;
00101
00102 if( str == NULL || ht == NULL || ht->ntot == 0 ) return NULL ;
00103
00104 jj = hashkey(str) % ht->len ;
00105
00106 vtab = ht->vtab ;
00107
00108 if( vtab[jj] == NULL ) return NULL ;
00109
00110 key = str ;
00111
00112 ctab = ht->ctab[jj] ; ntab = ht->ntab[jj] ;
00113
00114 for( kk=0 ; kk < ntab ; kk++ )
00115 if( ctab[kk] != NULL && strcmp(key,ctab[kk]) == 0 )
00116 return vtab[jj][kk];
00117
00118 return NULL ;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 void addto_Htable( char *str , void *vpt , Htable *ht )
00130 {
00131 UINT jj ;
00132 int kk , ll=-1 ;
00133 char *key ;
00134
00135
00136
00137 if( str == NULL || ht == NULL ) return ;
00138
00139 if( vpt == NULL ){ removefrom_Htable( str , ht ) ; return ; }
00140
00141 jj = hashkey(str) % ht->len ;
00142
00143 key = strdup(str) ;
00144
00145 if( ht->vtab[jj] == NULL ){
00146
00147 ht->vtab[jj] = (void **) calloc(3,sizeof(void *)) ;
00148 ht->ctab[jj] = (char **) calloc(3,sizeof(char *)) ;
00149 ht->ntab[jj] = 3 ;
00150
00151 ht->vtab[jj][0] = vpt ;
00152 ht->ctab[jj][0] = key ;
00153 ht->ntot ++ ;
00154
00155 } else {
00156
00157 for( kk=0 ; kk < ht->ntab[jj] ; kk++ ){
00158 if( ht->ctab[jj][kk] == NULL ){ if(ll < 0) ll=kk; }
00159 else if( strcmp(key,ht->ctab[jj][kk]) == 0 ) break ;
00160 }
00161
00162 if( kk == ht->ntab[jj] ){
00163
00164 if( ll >= 0 ){
00165
00166 ht->vtab[jj][ll] = vpt ;
00167 ht->ctab[jj][ll] = key ;
00168 ht->ntot ++ ;
00169
00170 } else {
00171
00172 ht->vtab[jj] = (void **) realloc( ht->vtab[jj] , (kk+3)*sizeof(void *)) ;
00173 ht->ctab[jj] = (char **) realloc( ht->ctab[jj] , (kk+3)*sizeof(char *)) ;
00174 ht->ntab[jj] = kk+3 ;
00175
00176 ht->vtab[jj][kk] = vpt ;
00177 ht->ctab[jj][kk] = key ;
00178 ht->ntot ++ ;
00179
00180 ht->vtab[jj][kk+1] = ht->vtab[jj][kk+2] = NULL ;
00181 ht->ctab[jj][kk+1] = ht->ctab[jj][kk+2] = NULL ;
00182
00183 }
00184
00185 } else {
00186
00187 if( vtkill && ht->vtab[jj][kk] != NULL ) free(ht->vtab[jj][kk]) ;
00188
00189 ht->vtab[jj][kk] = vpt ;
00190 free(key) ;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199 void removefrom_Htable( char *str , Htable *ht )
00200 {
00201 UINT jj ;
00202 int kk ;
00203 char *key ;
00204 void ***vtab ;
00205 char **ctab ;
00206 int ntab ;
00207
00208 if( str == NULL || ht == NULL || ht->ntot == 0 ) return ;
00209
00210 jj = hashkey(str) % ht->len ;
00211
00212 vtab = ht->vtab ;
00213
00214 if( vtab[jj] == NULL ) return ;
00215
00216 key = str ;
00217
00218 ctab = ht->ctab[jj] ; ntab = ht->ntab[jj] ;
00219
00220 for( kk=0 ; kk < ntab ; kk++ )
00221 if( ctab[kk] != NULL && strcmp(key,ctab[kk]) == 0 ){
00222 free(ctab[kk]); ctab[kk] = NULL;
00223 if( vtkill && vtab[jj][kk] != NULL ) free(vtab[jj][kk]) ;
00224 vtab[jj][kk] = NULL; ht->ntot--; break;
00225 }
00226
00227 return ;
00228 }
00229
00230
00231
00232
00233
00234 void profile_Htable( char *str, Htable *ht )
00235 {
00236 int jj, kk , nn ;
00237
00238 printf("\n----- Htable profile: %s\n",(str != NULL) ? str : "" ) ;
00239 if( ht == NULL ){
00240 printf("++ EMPTY ++\n") ; return ;
00241 }
00242
00243 printf("Rows=%d Ntot=%d\n",ht->len,ht->ntot) ;
00244
00245 for( jj=0 ; jj < ht->len ; jj++ ){
00246 printf(" #%05d: ",jj) ;
00247 if( ht->vtab[jj] == NULL ){
00248 printf("++ EMPTY ++\n") ;
00249 } else {
00250 for( nn=kk=0 ; kk < ht->ntab[jj] ; kk++ ){
00251 if( ht->ctab[jj][kk] != NULL ){ printf("*") ; nn++ ; }
00252 else { printf(".") ; }
00253 }
00254 printf(" [ntab=%d nn=%d]\n",ht->ntab[jj],nn) ;
00255 }
00256 }
00257 fflush(stdout) ;
00258 }
00259
00260
00261
00262
00263
00264 void subsume_Htable( Htable *htold , Htable *htnew )
00265 {
00266 int kk,jj ;
00267
00268
00269
00270 if( htold == NULL || htold->ntot == 0 || htnew == NULL ) return ;
00271
00272 for( jj=0 ; jj < htold->len ; jj++ ){
00273 if( htold->vtab[jj] != NULL ){
00274 for( kk=0 ; kk < htold->ntab[jj] ; kk++ )
00275 if( htold->ctab[jj][kk] != NULL )
00276 addto_Htable( htold->ctab[jj][kk] , htold->vtab[jj][kk] , htnew ) ;
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284
00285 void resize_Htable( int newlen , Htable *ht )
00286 {
00287 Htable *htnew ;
00288 int jj , kk ;
00289
00290 if( ht == NULL ) return ;
00291
00292
00293
00294 if( newlen == 0 ){
00295 if( ht->ntot <= 131 * ht->len ) return ;
00296 newlen = ht->ntot / 37 ;
00297 }
00298
00299
00300
00301 htnew = new_Htable( newlen ) ;
00302 if( htnew == NULL ) return ;
00303
00304 subsume_Htable( ht , htnew ) ;
00305
00306
00307
00308 for( jj=0 ; jj < ht->len ; jj++ ){
00309 if( ht->vtab[jj] != NULL ) free(ht->vtab[jj]) ;
00310
00311 if( ht->ctab[jj] != NULL ){
00312 for( kk=0 ; kk < ht->ntab[jj] ; kk++ )
00313 if( ht->ctab[jj][kk] != NULL ) free(ht->ctab[jj][kk]) ;
00314 free(ht->ctab[jj]) ;
00315 }
00316 }
00317 free(ht->vtab) ; free(ht->ctab) ; free(ht->ntab) ;
00318
00319
00320
00321 *ht = *htnew ;
00322
00323
00324
00325 free((void *)htnew) ; return ;
00326 }