00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/data_structures.h>
00017
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Data_structures/hash_table.c,v 1.13 2000/02/06 15:30:11 stever Exp $";
00020
#endif
00021
00022 #define HASH_FUNCTION_CONSTANT 0.6180339887498948482
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 public void initialize_hash_table(
00042
hash_table_struct *hash_table,
00043
int size,
00044
int data_size,
00045 Real enlarge_threshold,
00046 Real new_density )
00047 {
00048
int i;
00049
00050 hash_table->
size = size;
00051 hash_table->
data_size = data_size;
00052 hash_table->
n_entries = 0;
00053 hash_table->
enlarge_threshold = enlarge_threshold;
00054 hash_table->
new_density = new_density;
00055
00056 ALLOC( hash_table->
table, size );
00057
00058
for( i = 0; i < size; ++i )
00059 hash_table->
table[i] = NULL;
00060 }
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 private void delete_hash_table_list(
00076
hash_table_struct *hash_table )
00077 {
00078
if( hash_table->
size > 0 )
00079 FREE( hash_table->
table );
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 public void delete_hash_table(
00096
hash_table_struct *hash_table )
00097 {
00098
int i;
00099
hash_entry_struct *entry, *next;
00100
00101
for( i = 0; i < hash_table->
size; ++i )
00102 {
00103 entry = hash_table->
table[i];
00104
00105
while( entry != NULL )
00106 {
00107 next = entry->
next;
00108 FREE( entry );
00109 entry = next;
00110 }
00111 }
00112
00113
delete_hash_table_list( hash_table );
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 private int hash_function(
00132
hash_table_struct *hash_table,
00133
int key )
00134 {
00135
int index;
00136 Real v;
00137
00138 v = (Real) key *
HASH_FUNCTION_CONSTANT;
00139
00140 index = (
int) (FRACTION(v) * (Real) hash_table->
size);
00141
00142
return( index );
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 private hash_entry_struct **
lookup(
00161
hash_table_struct *hash_table,
00162
int key )
00163 {
00164
int i;
00165
hash_entry_struct **ptr_to_entry;
00166
00167 i =
hash_function( hash_table, key );
00168
00169 ptr_to_entry = &hash_table->
table[i];
00170
00171
while( *ptr_to_entry != NULL && (*ptr_to_entry)->
key != key )
00172 ptr_to_entry = &(*ptr_to_entry)->
next;
00173
00174
return( ptr_to_entry );
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 public void insert_in_hash_table(
00193
hash_table_struct *hash_table,
00194
int key,
00195
void *data_ptr )
00196 {
00197
hash_entry_struct **ptr_to_entry;
00198
hash_entry_struct *entry;
00199
00200 ptr_to_entry =
lookup( hash_table, key );
00201
00202 entry = *ptr_to_entry;
00203
00204
if( entry == NULL )
00205 {
00206 ALLOC_VAR_SIZED_STRUCT( entry,
char, hash_table->
data_size );
00207
00208 entry->
key = key;
00209 entry->
next = *ptr_to_entry;
00210 (
void) memcpy( (
void *) entry->
data, data_ptr,
00211 (size_t) hash_table->
data_size );
00212
00213 *ptr_to_entry = entry;
00214
00215 ++hash_table->
n_entries;
00216
00217
if( (Real) hash_table->
n_entries / (Real) hash_table->
size >
00218 hash_table->
enlarge_threshold )
00219 {
00220
int new_size;
00221
00222 new_size = ROUND( (Real) hash_table->
n_entries /
00223 hash_table->
new_density );
00224
increase_hash_table_size( hash_table, new_size );
00225 }
00226 }
00227
else
00228 {
00229 print_error(
"Insert in hash table: entry already present: %d\n", key );
00230 }
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 public BOOLEAN
lookup_in_hash_table(
00249
hash_table_struct *hash_table,
00250
int key,
00251
void *data_ptr )
00252 {
00253 BOOLEAN found;
00254
hash_entry_struct **ptr_to_entry;
00255
hash_entry_struct *entry;
00256
00257 ptr_to_entry =
lookup( hash_table, key );
00258
00259 entry = *ptr_to_entry;
00260
00261
if( entry == NULL )
00262 {
00263 found =
FALSE;
00264 }
00265
else
00266 {
00267
if( data_ptr != NULL )
00268 {
00269 (
void) memcpy( data_ptr, (
void *) entry->
data,
00270 (size_t) hash_table->
data_size );
00271 }
00272
00273 found =
TRUE;
00274 }
00275
00276
return( found );
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 public BOOLEAN
remove_from_hash_table(
00295
hash_table_struct *hash_table,
00296
int key,
00297
void *data_ptr )
00298 {
00299 BOOLEAN removed;
00300
hash_entry_struct **ptr_to_entry;
00301
hash_entry_struct *entry;
00302
00303 ptr_to_entry =
lookup( hash_table, key );
00304
00305 entry = *ptr_to_entry;
00306
00307
if( entry == NULL )
00308 {
00309 removed =
FALSE;
00310 }
00311
else
00312 {
00313
if( data_ptr != NULL )
00314 {
00315 (
void) memcpy( data_ptr, (
void *) entry->
data,
00316 (size_t) hash_table->
data_size );
00317 }
00318
00319 *ptr_to_entry = entry->
next;
00320
00321 FREE( entry );
00322
00323 removed =
TRUE;
00324 --hash_table->
n_entries;
00325 }
00326
00327
return( removed );
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 private void move_hash_entries_to_new_table(
00345
hash_table_struct *dest,
00346
hash_table_struct *src )
00347 {
00348
int i, hash;
00349
hash_entry_struct *entry, *next;
00350
00351
for( i = 0; i < src->
size; ++i )
00352 {
00353 entry = src->
table[i];
00354
00355
while( entry != NULL )
00356 {
00357 next = entry->
next;
00358
00359 hash =
hash_function( dest, entry->
key );
00360 entry->
next = dest->
table[hash];
00361 dest->
table[hash] = entry;
00362 ++dest->
n_entries;
00363
00364 entry = next;
00365 }
00366
00367 src->
table[i] = NULL;
00368 }
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 public void increase_hash_table_size(
00388
hash_table_struct *hash_table,
00389
int new_size )
00390 {
00391
hash_table_struct new_table;
00392
00393
initialize_hash_table( &new_table, new_size, hash_table->
data_size,
00394 hash_table->
enlarge_threshold,
00395 hash_table->
new_density );
00396
00397
move_hash_entries_to_new_table( &new_table, hash_table );
00398
00399
delete_hash_table_list( hash_table );
00400
00401 *hash_table = new_table;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 public void initialize_hash_pointer(
00419
hash_table_pointer *ptr )
00420 {
00421 ptr->
current_index = -1;
00422 ptr->
current_entry = NULL;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 public BOOLEAN
get_next_hash_entry(
00441
hash_table_struct *hash_table,
00442
hash_table_pointer *ptr,
00443
void *data_ptr )
00444 {
00445 BOOLEAN found;
00446
00447
if( ptr->
current_entry != NULL )
00448 ptr->
current_entry = ptr->
current_entry->
next;
00449
00450
if( ptr->
current_entry == NULL )
00451 {
00452
do
00453 {
00454 ++ptr->
current_index;
00455 }
00456
while( ptr->
current_index < hash_table->
size &&
00457 hash_table->
table[ptr->
current_index] == NULL );
00458
00459
if( ptr->
current_index < hash_table->
size )
00460 ptr->
current_entry = hash_table->
table[ptr->
current_index];
00461 }
00462
00463 found = (ptr->
current_entry != NULL);
00464
00465
if( found && data_ptr != NULL )
00466 {
00467 (
void) memcpy( data_ptr, (
void *) ptr->
current_entry->
data,
00468 (size_t) hash_table->
data_size );
00469 }
00470
00471
return( found );
00472 }