22 #define INT_PER_DOUBLE 2
50 int d1eq(
void* key1,
void* key2 );
76 bucket = table->
table;
84 for ( i = 0; i < size; ++i )
109 for ( i = 0; i < table->
size; ++i )
113 for ( bucket = ( table->
table )[i]; bucket != NULL; )
118 bucket = bucket->
next;
123 free( table->
table );
137 unsigned int val = table->
hash( key ) % (
unsigned int) table->
size;
145 if ( ( table->
table )[val] == NULL )
148 if ( bucket == NULL )
151 bucket->key = table->
cp( key );
154 bucket->id = table->
naccum;
156 ( table->
table )[val] = bucket;
168 for ( bucket = ( table->
table )[val]; bucket != NULL; bucket = bucket->next )
169 if ( table->
eq( key, bucket->key ) == 1 )
171 void* old_data = bucket->data;
174 bucket->id = table->
naccum;
189 if ( bucket == NULL )
191 bucket->key = table->
cp( key );
193 bucket->next = ( table->
table )[val];
194 bucket->id = table->
naccum;
196 ( table->
table )[val] = bucket;
212 unsigned int val = table->
hash( key ) % (
unsigned int) table->
size;
215 if ( ( table->
table )[val] == NULL )
218 for ( bucket = ( table->
table )[val]; bucket != NULL; bucket = bucket->next )
219 if ( table->
eq( key, bucket->key ) == 1 )
235 unsigned int val = table->
hash( key ) % (
unsigned int) table->
size;
240 if ( ( table->
table )[val] == NULL )
250 for ( prev = NULL, bucket = ( table->
table )[val]; bucket != NULL; prev = bucket, bucket = bucket->next )
252 if ( table->
eq( key, bucket->key ) == 1 )
256 prev->next = bucket->next;
266 ( table->
table )[val] = bucket->next;
294 for ( i = 0; i < table->
size; ++i )
295 if ( ( table->
table )[i] != NULL )
299 for ( bucket = ( table->
table )[i]; bucket != NULL; bucket = bucket->
next )
300 func( bucket->
data );
310 char * str = (
char *) key;
311 unsigned int hashvalue = 0;
315 hashvalue ^= *(
unsigned int *) str;
325 return (
void *) strdup( (
const char *) key );
328 static int streq(
void* key1,
void* key2 )
330 return !strcmp( key1, key2 );
337 unsigned int* v = (
unsigned int *) key;
339 #if INT_PER_DOUBLE == 2
342 #error not implemented
348 double* newkey = malloc(
sizeof (
double ) );
350 *newkey = *(
double *) key;
355 int d1eq(
void* key1,
void* key2 )
357 return *(
double *) key1 == *(
double *) key2;
368 unsigned int* v = (
unsigned int *) key;
370 #if INT_PER_DOUBLE == 2
375 return v[0] + v[1] + v[2] * 3 + v[3] * 7;
377 #error not implemented
383 double* newkey = malloc(
sizeof (
double ) * 2 );
385 newkey[0] = ( (
double *) key )[0];
386 newkey[1] = ( (
double *) key )[1];
391 static int d2eq(
void* key1,
void* key2 )
393 return ( ( (
double *) key1 )[0] == ( (
double *) key2 )[0] ) && ( ( (
double *) key1 )[1] == ( (
double *) key2 )[1] );
418 static void print_double(
void* data )
420 printf(
" \"%d\"", (
int) *(
double *) data );
423 static void print_string(
void* data )
425 printf(
" \"%s\"", (
char *) data );
431 922803.7855, 7372394.688, 0,
432 922849.2037, 7372307.027, 1,
433 922894.657, 7372219.306, 2,
434 922940.1475, 7372131.528, 3,
435 922985.6777, 7372043.692, 4,
436 923031.2501, 7371955.802, 5,
437 923076.8669, 7371867.857, 6,
438 923122.5307, 7371779.861, 7,
439 923168.2439, 7371691.816, 8,
440 923214.0091, 7371603.722, 9,
441 923259.8288, 7371515.583, 10,
442 922891.3958, 7372440.117, 11,
443 922936.873, 7372352.489, 12,
444 922982.3839, 7372264.804, 13,
445 923027.9308, 7372177.064, 14,
446 923073.5159, 7372089.268, 15,
447 923119.1415, 7372001.42, 16,
448 923164.8099, 7371913.521, 17,
449 923210.5233, 7371825.572, 18,
450 923256.2841, 7371737.575, 19,
451 923302.0946, 7371649.534, 20,
452 923347.9572, 7371561.45, 21,
453 922978.9747, 7372485.605, 22,
454 923024.5085, 7372398.009, 23,
455 923070.0748, 7372310.358, 24,
456 923115.6759, 7372222.654, 25,
457 923161.3136, 7372134.897, 26,
458 923206.9903, 7372047.09, 27,
459 923252.7079, 7371959.233, 28,
460 923298.4686, 7371871.33, 29,
461 923344.2745, 7371783.381, 30,
462 923390.1279, 7371695.389, 31,
463 923436.0309, 7371607.357, 32,
464 923066.5232, 7372531.148, 33,
465 923112.1115, 7372443.583, 34,
466 923157.7311, 7372355.966, 35,
467 923203.3842, 7372268.296, 36,
468 923249.0725, 7372180.577, 37,
469 923294.7981, 7372092.808, 38,
470 923340.5628, 7372004.993, 39,
471 923386.3686, 7371917.132, 40,
472 923432.2176, 7371829.229, 41,
473 923478.1116, 7371741.284, 42,
474 923524.0527, 7371653.302, 43,
475 923154.0423, 7372576.746, 44,
476 923199.6831, 7372489.211, 45,
477 923245.3541, 7372401.625, 46,
478 923291.0572, 7372313.989, 47,
479 923336.7941, 7372226.305, 48,
480 923382.5667, 7372138.574, 49,
481 923428.3766, 7372050.798, 50,
482 923474.2256, 7371962.978, 51,
483 923520.1155, 7371875.118, 52,
484 923566.0481, 7371787.218, 53,
485 923612.0252, 7371699.282, 54,
486 923241.533, 7372622.396, 55,
487 923287.2244, 7372534.889, 56,
488 923332.9449, 7372447.334, 57,
489 923378.6963, 7372359.731, 58,
490 923424.4801, 7372272.081, 59,
491 923470.2979, 7372184.385, 60,
492 923516.1513, 7372096.646, 61,
493 923562.0418, 7372008.866, 62,
494 923607.9709, 7371921.046, 63,
495 923653.9402, 7371833.188, 64,
496 923699.9514, 7371745.296, 65,
497 923328.9962, 7372668.095, 66,
498 923374.7365, 7372580.617, 67,
499 923420.5049, 7372493.091, 68,
500 923466.303, 7372405.519, 69,
501 923512.1321, 7372317.901, 70,
502 923557.9936, 7372230.24, 71,
503 923603.8889, 7372142.536, 72,
504 923649.8192, 7372054.793, 73,
505 923695.786, 7371967.011, 74,
506 923741.7905, 7371879.193, 75,
507 923787.8341, 7371791.342, 76,
508 923416.4327, 7372713.844, 77,
509 923462.2204, 7372626.393, 78,
510 923508.0353, 7372538.895, 79,
511 923553.8787, 7372451.353, 80,
512 923599.7517, 7372363.766, 81,
513 923645.6555, 7372276.137, 82,
514 923691.5914, 7372188.467, 83,
515 923737.5603, 7372100.757, 84,
516 923783.5634, 7372013.011, 85,
517 923829.6017, 7371925.231, 86,
518 923875.6763, 7371837.419, 87,
519 923503.8433, 7372759.64, 88,
520 923549.6771, 7372672.214, 89,
521 923595.5372, 7372584.744, 90,
522 923641.4246, 7372497.23, 91,
523 923687.3404, 7372409.673, 92,
524 923733.2855, 7372322.074, 93,
525 923779.2608, 7372234.436, 94,
526 923825.2672, 7372146.759, 95,
527 923871.3056, 7372059.047, 96,
528 923917.3766, 7371971.301, 97,
529 923963.4812, 7371883.524, 98,
530 923591.2288, 7372805.481, 99,
531 923637.1076, 7372718.081, 100,
532 923683.0118, 7372630.638, 101,
533 923728.9423, 7372543.151, 102,
534 923774.8998, 7372455.622, 103,
535 923820.8852, 7372368.052, 104,
536 923866.8991, 7372280.443, 105,
537 923912.9422, 7372192.797, 106,
538 923959.015, 7372105.116, 107,
539 924005.118, 7372017.402, 108,
540 924051.2518, 7371929.657, 109,
541 923678.5898, 7372851.367, 110,
542 923724.5126, 7372763.992, 111,
543 923770.46, 7372676.574, 112,
544 923816.4328, 7372589.113, 113,
545 923862.4314, 7372501.611, 114,
546 923908.4564, 7372414.069, 115,
547 923954.5083, 7372326.488, 116,
548 924000.5875, 7372238.87, 117,
549 924046.6941, 7372151.218, 118,
550 924092.8286, 7372063.533, 119,
551 924138.9911, 7371975.818, 120
554 int size =
sizeof ( points ) /
sizeof (
double ) / 3;
562 printf(
"\n1. Testing a table with key of double[2] type\n\n" );
564 printf(
" creating a table..." );
568 printf(
" inserting %d values from a file...", size );
569 for ( i = 0; i < size; ++i )
570 ht_insert( ht, &points[i * 3], &points[i * 3 + 2] );
573 printf(
" stats:\n" );
574 printf(
" %d entries, %d table elements, %d filled elements\n", ht->
n, ht->
size, ht->
nhash );
575 printf(
" %f entries per hash value in use\n", (
double) ht->
n / ht->
nhash );
577 printf(
" finding and printing each 10th data:\n" );
578 for ( i = 0; i < size; i += 10 )
580 double*
point = &points[i * 3];
581 double* data =
ht_find( ht, point );
584 printf(
" i = %d; data = \"%d\"\n", i, (
int) *data );
586 printf(
" i = %d; data = <none>\n", i );
589 printf(
" removing every 3rd element..." );
590 for ( i = 0; i < size; i += 3 )
592 double* point = &points[i * 3];
597 printf(
" stats:\n" );
598 printf(
" %d entries, %d table elements, %d filled elements\n", ht->
n, ht->
size, ht->
nhash );
599 printf(
" %f entries per hash value in use\n", (
double) ht->
n / ht->
nhash );
601 printf(
" finding and printing each 10th data:\n" );
602 for ( i = 0; i < size; i += 10 )
604 double* point = &points[i * 3];
605 double* data =
ht_find( ht, point );
608 printf(
" i = %d; data = \"%d\"\n", i, (
int) *data );
610 printf(
" i = %d; data = <none>\n", i );
613 printf(
" printing all data by calling ht_process():\n " );
616 printf(
"\n destroying the hash table..." );
624 printf(
"\n2. Testing a table with key of char* type\n\n" );
626 printf(
" creating a table..." );
630 printf(
" inserting %d elements with deep copy of each data string...", size );
631 for ( i = 0; i < size; ++i )
637 sprintf( key,
"%d-th key", i );
638 sprintf( str,
"%d-th data", i );
639 data = strdup( str );
644 printf(
" stats:\n" );
645 printf(
" %d entries, %d table elements, %d filled elements\n", ht->
n, ht->
size, ht->
nhash );
646 printf(
" %f entries per hash value in use\n", (
double) ht->
n / ht->
nhash );
648 printf(
" finding and printing each 10th data:\n" );
649 for ( i = 0; i < size; i += 10 )
654 sprintf( key,
"%d-th key", i );
657 printf(
" i = %d; data = \"%s\"\n", i, data );
659 printf(
" i = %d; data = <none>\n", i );
662 printf(
" removing every 3rd element..." );
663 for ( i = 0; i < size; i += 3 )
667 sprintf( key,
"%d-th key", i );
672 printf(
" stats:\n" );
673 printf(
" %d entries, %d table elements, %d filled elements\n", ht->
n, ht->
size, ht->
nhash );
674 printf(
" %f entries per hash value in use\n", (
double) ht->
n / ht->
nhash );
676 printf(
" finding and printing each 10th data:\n" );
677 for ( i = 0; i < size; i += 10 )
682 sprintf( key,
"%d-th key", i );
685 printf(
" i = %d; data = \"%s\"\n", i, data );
687 printf(
" i = %d; data = <none>\n", i );
690 printf(
" printing all data by calling ht_process():\n " );
693 printf(
"\n freeing the remaining data by calling ht_process()..." );
697 printf(
" destroying the hash table..." );
void * ht_find(hashtable *table, void *key)
void * ht_delete(hashtable *table, void *key)
int d1eq(void *key1, void *key2)
static void * d2cp(void *key)
hashtable * ht_create(int size, ht_keycp cp, ht_keyeq eq, ht_key2hash hash)
void ht_destroy(hashtable *table)
static void * d1cp(void *key)
hashtable * ht_create_str(int size)
struct ht_bucket ht_bucket
hashtable * ht_create_d1(int size)
unsigned int(* ht_key2hash)(void *)
static unsigned int d1hash(void *key)
int(* ht_keyeq)(void *, void *)
void ht_process(hashtable *table, void(*func)(void *))
static void * strcp(void *key)
static unsigned int d2hash(void *key)
static unsigned int strhash(void *key)
static int streq(void *key1, void *key2)
void * ht_insert(hashtable *table, void *key, void *data)
static int d2eq(void *key1, void *key2)
hashtable * ht_create_d2(int size)
void *(* ht_keycp)(void *)