00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef __it_hlist_h
00039 #define __it_hlist_h
00040
00041 #ifndef __it_hlist_h_
00042 #define __it_hlist_h_
00043
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <assert.h>
00048 #include <stdint.h>
00049 #include <sys/param.h>
00050 #ifdef linux
00051 # include <endian.h>
00052 #endif
00053
00054
00055 #define __HLIST_MAXLEN 12
00056 #define __HLIST_OUTPUT stderr
00057
00058
00059 typedef struct cell_t
00060 {
00061 struct cell_t * prev, * next;
00062 void * content;
00063 unsigned short csz;
00064 } *cell, *list;
00065
00066
00067 typedef struct list_header_t
00068 {
00069 char * lname;
00070 FILE * out;
00071 unsigned int count;
00072 } list_header;
00073
00074
00075 typedef struct head_t
00076 {
00077 list_header h;
00078 struct cell_t data;
00079 } * head;
00080
00081 typedef list fifo;
00082 typedef list lifo;
00083
00084
00085
00086 #define __object_set_field( o, field, value ) do { \
00087 memcpy( &((o).field), &(value), sizeof(value); \
00088 } while ( 0 )
00089
00090
00091 #define __object_get_field( o, field, value ) do { \
00092 memcpy( &(value), &((o).field), sizeof(value); \
00093 } while ( 0 )
00094
00095
00096 #define __get_header(l) ((head)( (char *)(l)-sizeof( list_header )))
00097
00098
00099
00100 #define __idx_value(target,object,idx) \
00101 (&(target)?*((int*)(((char*)(target))+((unsigned int)((char*)&(object).idx-(char*)&(object))))):-1)
00102
00103
00104 #define __new_cell( c ) do { \
00105 (c) = malloc( sizeof( *(c) ) ); \
00106 (c)->content = NULL; \
00107 (c)->prev = (c); \
00108 (c)->next = (c); \
00109 } while ( 0 )
00110
00111
00112 #define __cell_print( c, out ) do { \
00113 fprintf( (out), "cell @ %p: prev @ %p, next @ %p (content @ %p, %d bytes)\n", (void*)(c), (void*)(c)->prev, (void*)(c)->next, (void*)(c)->content, (c)->csz ); \
00114 } while ( 0 )
00115
00116
00117
00118 #define __list_init_prealloc( l ) do { \
00119 head hl = malloc( sizeof( *hl ) ); \
00120 hl->h.count = 0; \
00121 hl->h.lname = NULL; \
00122 hl->h.out = __HLIST_OUTPUT; \
00123 (l) = (list)&(hl->data); \
00124 (l)->content = NULL; \
00125 (l)->prev = l; \
00126 (l)->next = l; \
00127 } while ( 0 )
00128
00129
00130 #define __list_init( l ) __list_init_prealloc( l )
00131
00132
00133 #define __list_get_count( l, cnt ) do { \
00134 head hl = __get_header(l); \
00135 assert( sizeof( (cnt) ) == sizeof( hl->h.count ) ); \
00136 memcpy( &(cnt), &(hl->h.count), sizeof( (cnt) ) ); \
00137 } while ( 0 )
00138
00139
00140 #define __list_decr_count( l ) do { \
00141 head hl = __get_header(l); \
00142 hl->h.count--; \
00143 } while ( 0 ) \
00144
00145
00146 #define __list_set_count( l, n ) do { \
00147 head hl = __get_header(l); \
00148 hl->h.count = n; \
00149 } while ( 0 )
00150
00151
00152 #define __list_incr_count( l ) do { \
00153 head hl = __get_header(l); \
00154 hl->h.count++; \
00155 } while ( 0 ) \
00156
00157
00158 #define __list_set_output( l, file ) do { \
00159 head hl = __get_header(l); \
00160 fprintf( stderr, "Warning: Changing output!\n" ); \
00161 hl->h.out = (file); \
00162 } while( 0 )
00163
00164
00165 #define __list_set_name( l, newname ) do { \
00166 unsigned int i, len; \
00167 head hl = __get_header(l); \
00168 len = strlen(newname)+1<__HLIST_MAXLEN?strlen(newname):__HLIST_MAXLEN; \
00169 if ( hl->h.lname ) \
00170 { \
00171 fprintf( stderr, "Warning: Changing name!\n" ); \
00172 free( hl->h.lname ); \
00173 } \
00174 hl->h.lname = malloc( (1+strlen(newname))*sizeof(char) ); \
00175 for ( i= 0; i< len; i++ ) hl->h.lname[i] = newname[i]; \
00176 hl->h.lname[i] = '\0'; \
00177 } while ( 0 ) \
00178
00179
00180 #define __list_print_header( l ) do { \
00181 head hl = __get_header(l); \
00182 if ( hl->h.lname ) \
00183 fprintf( hl->h.out, "List %s @ %p ", hl->h.lname, (void*)(l) ); \
00184 else \
00185 fprintf( hl->h.out, "List @ %p ", (void*)l ); \
00186 if ( hl->h.count==1 || hl->h.count==0) \
00187 fprintf( hl->h.out, "(%d item)\n", hl->h.count ); \
00188 else \
00189 fprintf( hl->h.out, "(%d items)\n", hl->h.count ); \
00190 } while ( 0 ) \
00191
00192
00193
00194 #define __list_is_empty( l, empty ) do { \
00195 __list_get_count( l, empty ); \
00196 empty = !empty; \
00197 } while ( 0 )
00198
00199
00200 #define __list_add_first( l, object ) do { \
00201 cell c; \
00202 __new_cell( c ); \
00203 c->next = (l)->next; \
00204 c->prev = (l); \
00205 (l)->next->prev = c; \
00206 (l)->next = c; \
00207 c->content = malloc( sizeof( object ) ); \
00208 c->csz = sizeof(object); \
00209 memcpy( (c->content), &(object), sizeof( object) ); \
00210 __list_incr_count( l ); \
00211 } while(0)
00212
00213
00214 #define __list_add_last( l, object ) do { \
00215 cell c; \
00216 __new_cell( c ); \
00217 c->prev = (l)->prev; \
00218 c->next = (l); \
00219 (l)->prev->next = c; \
00220 (l)->prev = c; \
00221 c->content = malloc( sizeof( object ) ); \
00222 c->csz = sizeof(object); \
00223 memcpy( c->content, &(object), sizeof( object) ); \
00224 __list_incr_count( l ); \
00225 } while(0)
00226
00227
00228 #define __list_add_by_index( l, object, index ) do { \
00229 cell c; \
00230 cell i = (l)->next; \
00231 while( i->content && (object).index > __idx_value( i->content, object, index ) ) \
00232 i = i->next; \
00233 i = i->prev; \
00234 __new_cell( c ); \
00235 c->next = (i)->next; \
00236 c->prev = (i); \
00237 (i)->next->prev = c; \
00238 (i)->next = c; \
00239 c->content = malloc( sizeof( object ) ); \
00240 c->csz = sizeof(object); \
00241 memcpy( c->content, &(object), sizeof( object) ); \
00242 __list_incr_count( l ); \
00243 } while ( 0 )
00244
00245
00246 #define __list_add_by_index_reverse( l, object, index ) do { \
00247 cell c; \
00248 cell i = (l)->next; \
00249 while( i->content && (object).index < __idx_value( i->content, object, index ) ) \
00250 i = i->next; \
00251 i = i->prev; \
00252 __new_cell( c ); \
00253 c->next = (i)->next; \
00254 c->prev = (i); \
00255 (i)->next->prev = c; \
00256 (i)->next = c; \
00257 c->content = malloc( sizeof( object ) ); \
00258 c->csz = sizeof(object); \
00259 memcpy( c->content, &(object), sizeof( object) ); \
00260 __list_incr_count( l ); \
00261 } while ( 0 )
00262
00263
00264 #define __list_del_first_by_index( l, object, idx ) do { \
00265 cell c; \
00266 cell i = (l)->next; \
00267 while( i->content && (object).idx != __idx_value( i->content, object, idx ) ) \
00268 i = i->next; \
00269 if ( &(object) ) \
00270 memcpy( &(object), (i)->next->content, sizeof( (object) ) ); \
00271 if ( (i)->next->content ) { \
00272 free( (i)->next->content ); \
00273 c = (i)->next; \
00274 (i)->next->next->prev = (i); \
00275 (i)->next = (i)->next->next; \
00276 free( c ); \
00277 __list_decr_count( l ); \
00278 } \
00279 } while ( 0 )
00280
00281
00282 #define __list_del_all_by_index( l, object, idx ) do { \
00283 cell i = (l)->next, c; \
00284 while( i->content ) { \
00285 if ( (object).idx==__idx_value(i->content,object,idx) ) { \
00286 if ( &(object) ) \
00287 memcpy( &(object), i->content, sizeof( (object) ) ); \
00288 free( i->content ); \
00289 c = i; \
00290 i->next->prev = i->prev; \
00291 i->prev->next = i->next; \
00292 free( c ); \
00293 __list_decr_count( l ); \
00294 } \
00295 i = i->next; \
00296 } \
00297 } while ( 0 )
00298
00299
00300 #define __list_foreach_forward( l, i ) \
00301 for( (i)=(l)->next; (i)->content; (i) = (i)->next )
00302
00303
00304 #define __list_foreach_reverse( l, i ) \
00305 for( (i)=(l)->prev; (i)->content; (i) = (i)->prev )
00306
00307
00308 #define __list_foreach( l, i ) __list_foreach_forward( l, i )
00309
00310
00311 #define _save_list_print( l ) do { \
00312 cell c; \
00313 head hl = __get_header(l); \
00314 unsigned int sz = sizeof(*hl)+(hl->h.lname)?1+strlen(hl->h.lname):0; \
00315 unsigned int csz = 0; \
00316 __list_print_header( l ); \
00317 __list_foreach( l, c ) { \
00318 __cell_print( c, hl->h.out ); \
00319 csz+= c->csz; \
00320 sz+= sizeof(*c); \
00321 } \
00322 } while ( 0 )
00323
00324 #define __list_print( l ) do { \
00325 cell c; \
00326 head hl = __get_header(l); \
00327 unsigned int tsz = sizeof(*hl)+(hl->h.lname)?1+strlen(hl->h.lname):0; \
00328 unsigned int csz = 0; \
00329 __list_print_header( l ); \
00330 __list_foreach( l, c ) { \
00331 __cell_print( c, hl->h.out ); \
00332 csz+= c->csz; \
00333 tsz+= sizeof(*c); \
00334 } \
00335 fprintf( hl->h.out, "Content total: %d bytes\n", csz ); \
00336 } while ( 0 )
00337
00338
00339 #define __list_del_first( l, object ) do { \
00340 cell c; \
00341 if ( &(object) && (l)->next->content ) \
00342 memcpy( &(object), (l)->next->content, sizeof( (object) ) ); \
00343 if ( (l)->next->content ) { \
00344 free( (l)->next->content ); \
00345 c = (l)->next; \
00346 (l)->next->next->prev = (l); \
00347 (l)->next = (l)->next->next; \
00348 free( c ); \
00349 __list_decr_count( l ); \
00350 } \
00351 } while ( 0 )
00352
00353
00354 #define __list_del_last( l, object ) do { \
00355 cell c; \
00356 if ( &(object) ) \
00357 memcpy( &(object), (l)->prev->content, sizeof( (object) ) ); \
00358 if ( (l)->prev->content ) { \
00359 free( (l)->prev->content ); \
00360 c = (l)->prev; \
00361 (l)->prev->prev->next = (l); \
00362 (l)->prev = (l)->prev->prev; \
00363 free( c ); \
00364 __list_decr_count( l ); \
00365 } \
00366 } while ( 0 )
00367
00368
00369 #define __list_del_first_object( l, object ) do { \
00370 cell i = (l)->next; \
00371 while ( i->content && memcmp( i->content, &(object), sizeof(object) ) ) \
00372 i = i->next; \
00373 i = i->prev; \
00374 if ( (i)->next->content ) { \
00375 cell c; \
00376 free( (i)->next->content ); \
00377 c = (i)->next; \
00378 (i)->next->next->prev = (i); \
00379 (i)->next = (i)->next->next; \
00380 free( c ); \
00381 __list_decr_count( l ); \
00382 } \
00383 } while ( 0 )
00384
00385
00386 #define __list_del_all_object( l, object ) do { \
00387 cell i = (l)->next; \
00388 while ( i->content ) { \
00389 if ( !memcmp( i->content, &(object), sizeof(object) ) ) { \
00390 cell c; \
00391 i = i->prev; \
00392 free( (i)->next->content ); \
00393 c = i->next; \
00394 (i)->next->next->prev = i; \
00395 (i)->next = (i)->next->next; \
00396 free( c ); \
00397 __list_decr_count( l ); \
00398 } \
00399 i = i->next; \
00400 } \
00401 } while ( 0 )
00402
00403
00404
00405
00406 #define __list_contains( l, object, found ) do { \
00407 cell i = (l)->next; \
00408 int f = -1; \
00409 memcpy( &(found), &f, sizeof(f) ); \
00410 while ( i->content ) { \
00411 f++; \
00412 if ( !memcmp( i->content, &(object), sizeof(object) ) ) { \
00413 memcpy( &(found), &f, sizeof(f) ); \
00414 break; \
00415 } \
00416 i = i->next; \
00417 } \
00418 } while ( 0 )
00419
00420
00421 #define __list_delete( l ) do { \
00422 unsigned int cnt; \
00423 cell c; \
00424 head hl = (head)( (char *)l-sizeof( (hl->h)) ); \
00425 __list_get_count( l, cnt ); \
00426 while( cnt ) { \
00427 free( (l)->next->content ); \
00428 c = (l)->next; \
00429 (l)->next->next->prev = (l); \
00430 (l)->next = (l)->next->next; \
00431 free( c ); \
00432 __list_decr_count( l ); \
00433 __list_get_count( l, cnt ); \
00434 } \
00435 if ( hl->h.lname ) { \
00436 free( hl->h.lname ); \
00437 hl->h.lname = NULL; \
00438 } \
00439 free( hl ); \
00440 } while( 0 )
00441
00442
00443 #define __list_apply_function( l, function ) do { \
00444 cell c; \
00445 __list_foreach_forward( l, c ) { \
00446 function( (c)->content ); \
00447 } \
00448 } while ( 0 )
00449
00450
00451
00452
00453
00454
00455 #define __list_compare(l1,l2,comp) do { \
00456 unsigned int s1, s2; \
00457 __list_get_count( l1, s1 ); \
00458 __list_get_count( l2, s2 ); \
00459 if ( s1 < s2 ) { \
00460 s1 = -1; \
00461 memcpy( &(comp), &s1, sizeof(comp) ); \
00462 } \
00463 if ( s1 > s2 ) { \
00464 s2 = 1; \
00465 memcpy( &(comp), &s2, sizeof(comp) ); \
00466 } \
00467 if ( s1==s2 ) { \
00468 unsigned int t = 0; \
00469 cell c1 = (l1)->next, c2 = (l2)->next; \
00470 while ( (c1)->content ) { \
00471 if ( (c1)->csz == (c2)->csz && !memcmp((c1)->content,(c2)->content, (c1)->csz)) { \
00472 c1 = c1->next; \
00473 c2 = c2->next; \
00474 } \
00475 else { \
00476 t = 1; \
00477 break; \
00478 } \
00479 } \
00480 memcpy( &(comp), &t, sizeof(t) ); \
00481 } \
00482 } while ( 0 )
00483
00484
00485 #define __list_append( l1, l2 ) do { \
00486 head hl1 = __get_header(l1); \
00487 head hl2 = __get_header(l2); \
00488 l1->prev->next = l2->next; \
00489 l2->next->prev = l1->prev; \
00490 l2->prev->next = l1; \
00491 hl1->h.count += hl1->h.count; \
00492 l2 = &(hl2->data); \
00493 if ( hl2->h.lname ) free( hl2->h.lname ); \
00494 free( hl2 ); \
00495 } while ( 0 )
00496
00497
00498
00499 #define __list_fusion( l1, l2 ) do { \
00500 cell cc; \
00501 __list_foreach( l2, cc ) { \
00502 unsigned int prst = 0; \
00503 cell c; \
00504 __list_foreach( l1, c ) { \
00505 if ( !memcmp( cc->content, c->content, sizeof(c->csz) ) ) \
00506 prst = 1; \
00507 } \
00508 if ( !prst ) { \
00509 cell t; \
00510 __new_cell( t ); \
00511 t->content = malloc( cc->csz ); \
00512 t->csz = cc->csz; \
00513 t->prev = (l1)->prev; \
00514 t->next = (l1); \
00515 (l1)->prev->next = t; \
00516 (l1)->prev = t; \
00517 memcpy( t->content, cc->content, cc->csz ); \
00518 __list_incr_count(l1); \
00519 } \
00520 } \
00521 } while ( 0 )
00522
00523
00524 #define __list_copy( l1, l2 ) do { \
00525 cell i; \
00526 head hl2 = __get_header( l2 ); \
00527 __list_init( l1 ); \
00528 __list_foreach( l2, i ) { \
00529 cell c; \
00530 __new_cell( c ); \
00531 c->prev = (l1)->prev; \
00532 c->next = (l1); \
00533 (l1)->prev->next = c; \
00534 (l1)->prev = c; \
00535 c->content = malloc( i->csz ); \
00536 c->csz = i->csz; \
00537 memcpy( c->content, i->content, c->csz ); \
00538 } \
00539 __list_set_count( l1, hl2->h.count ); \
00540 if ( hl2->h.lname ) __list_set_name( l1, hl2->h.lname ); \
00541 } while ( 0 )
00542
00543
00544 #define __list_insert_once( l,object ) do { \
00545 unsigned int prst = 0; \
00546 cell c; \
00547 __list_foreach( l, c ) { \
00548 if ( !memcmp( &(object), c->content, sizeof(object) ) && sizeof(object)==c->csz ) \
00549 prst = 1; \
00550 } \
00551 if ( !prst ) __list_add_first( l, object ); \
00552 } while ( 0 )
00553
00554
00555 #define __list_only_once( l ) do { \
00556 list r; \
00557 cell c; \
00558 unsigned int cnt; \
00559 __list_get_count( l, cnt ); \
00560 if ( cnt < 2 ) break; \
00561 __list_init( r ); \
00562 __new_cell( c ); \
00563 c->next = r->next; \
00564 c->prev = r; \
00565 r->next->prev = c; \
00566 r->next = c; \
00567 c->content = malloc( l->next->csz ); \
00568 c->csz = l->next->csz; \
00569 memcpy( c->content, l->next->content, l->next->csz ); \
00570 __list_incr_count( r ); \
00571 __list_foreach( l, c ) { \
00572 cell tt; \
00573 unsigned int prsnt = 0; \
00574 __list_foreach( r, tt ) { \
00575 if ( !memcmp( tt->content, c->content, c->csz ) && tt->csz==c->csz ) \
00576 prsnt = 1; \
00577 } \
00578 if ( !prsnt ) { \
00579 cell t; \
00580 __new_cell( t ); \
00581 t->next = r->next; \
00582 t->prev = r; \
00583 r->next->prev = t; \
00584 r->next = t; \
00585 t->content = malloc( c->csz ); \
00586 t->csz = c->csz; \
00587 memcpy( t->content, c->content, c->csz ); \
00588 __list_incr_count( r ); \
00589 } \
00590 } \
00591 __list_delete( l ); \
00592 l = r; \
00593 } while ( 0 )
00594
00595
00596 #define __list_minus(l1,l2) do { \
00597 cell c; \
00598 list cl1, cl2; \
00599 list r; \
00600 __list_init( r ); \
00601 __list_copy( cl1, l1 ); \
00602 __list_copy( cl2, l2 ); \
00603 __list_only_once( cl1 ); \
00604 __list_only_once( cl2 ); \
00605 __list_foreach(cl2,c) { \
00606 cell cc; \
00607 __list_foreach( cl1,cc ) { \
00608 if ( !memcmp(c->content, cc->content, c->csz) && c->csz==cc->csz ) { \
00609 cell t; \
00610 __new_cell( t ); \
00611 t->next = r->next; \
00612 t->prev = r; \
00613 r->next->prev = t; \
00614 r->next = t; \
00615 t->content = malloc( c->csz ); \
00616 t->csz = c->csz; \
00617 memcpy( t->content, c->content, c->csz ); \
00618 __list_incr_count( r ); \
00619 } \
00620 } \
00621 } \
00622 __list_delete( l1 ); \
00623 __list_delete( cl2 ); \
00624 __list_delete( cl1 ); \
00625 l1 = r; \
00626 } while ( 0 )
00627
00628
00629
00630
00631
00632 #define list_init(l) __list_init(l)
00633 #define list_set_name(l,name) __list_set_name(l,name)
00634 #define list_get_count(l,cnt) __list_get_count(l, cnt)
00635 #define list_set_count(l,cnt) __list_set_count(l, cnt)
00636 #define list_set_output(l,file) __list_set_output(l,file)
00637 #define list_is_empty(l,empty) __list_is_empty(l,empty)
00638 #define list_add_first(l,object) __list_add_first(l,object)
00639 #define list_add_last(l,object) __list_add_last(l,object)
00640 #define list_add_by_index(l,object,index) __list_add_by_index(l,object,index)
00641 #define list_add_by_index_reverse(l,object,index) __list_add_by_index_reverse(l,object,index)
00642 #define list_del_first_by_index(l,object,index) __list_del_first_by_index(l,object,index)
00643 #define list_del_all_by_index(l,object,index) __list_del_all_by_index(l,object,index)
00644 #define list_foreach(l,i) __list_foreach(l,i)
00645 #define list_foreach_reverse(l,i) __list_foreach_reverse(l,i)
00646 #define list_print(l) __list_print(l)
00647 #define list_del_first(l,object) __list_del_first(l,object)
00648 #define list_del_last(l,object) __list_del_last(l,object)
00649 #define list_delete(l) __list_delete(l)
00650 #define list_apply_function(l,function) __list_apply_function(l,function)
00651 #define list_compare(l1,l2,comp) __list_compare(l1,l2,comp)
00652 #define list_del_first_object(l,object) __list_del_first_object(l,object)
00653 #define list_del_all_object(l,object) __list_del_all_object(l,object)
00654 #define list_contains(l,object,found) __list_contains(l,object,found)
00655 #define list_append(l1,l2) __list_append(l1,l2)
00656 #define list_fusion(l1,l2) __list_fusion(l1,l2)
00657 #define list_copy(l1,l2) __list_copy(l1,l2)
00658 #define list_insert_once(l,object) __list_insert_once(l,object)
00659 #define list_only_once(l) __list_only_once(l)
00660
00661 #define fifo_init(f) __list_init(f)
00662 #define fifo_push(f,object) __list_add_first(f,object)
00663 #define fifo_pop(f,object) __list_del_last(f,object)
00664 #define fifo_delete(f) __list_delete(f)
00665
00666 #define lifo_init(l) __list_init(l)
00667 #define lifo_push(l,object) __list_add_first(l,object)
00668 #define lifo_pop(l,object) __list_del_first(l,object)
00669 #define lifo_delete(l) __list_delete(l)
00670
00671
00672
00673
00674 typedef struct hash_header_t {
00675 char * hname;
00676 FILE * out;
00677 unsigned int count;
00678 } hash_header;
00679
00680
00681 typedef struct hash_t {
00682 hash_header h;
00683 list * data;
00684 } * hash;
00685
00686
00687
00688
00689
00690
00691
00692
00693 #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
00694 __BYTE_ORDER == __LITTLE_ENDIAN) || \
00695 (defined(i386) || defined(__i386__) || defined(__i486__) || \
00696 defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
00697 # define HASH_LITTLE_ENDIAN 1
00698 # define HASH_BIG_ENDIAN 0
00699 #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
00700 __BYTE_ORDER == __BIG_ENDIAN) || \
00701 (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
00702 # define HASH_LITTLE_ENDIAN 0
00703 # define HASH_BIG_ENDIAN 1
00704 #else
00705 # define HASH_LITTLE_ENDIAN 0
00706 # define HASH_BIG_ENDIAN 0
00707 #endif
00708
00709 #define bj_hashsize(n) ((uint32_t)1<<(n))
00710 #define bj_hashmask(n) (bj_hashsize(n)-1)
00711 #define bj_rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
00712
00713 #define bj_mix(a,b,c) do { \
00714 a -= c; a ^= bj_rot(c, 4); c += b; \
00715 b -= a; b ^= bj_rot(a, 6); a += c; \
00716 c -= b; c ^= bj_rot(b, 8); b += a; \
00717 a -= c; a ^= bj_rot(c,16); c += b; \
00718 b -= a; b ^= bj_rot(a,19); a += c; \
00719 c -= b; c ^= bj_rot(b, 4); b += a; \
00720 } while ( 0 )
00721
00722 #define bj_final(a,b,c) do { \
00723 c ^= b; c -= bj_rot(b,14); \
00724 a ^= c; a -= bj_rot(c,11); \
00725 b ^= a; b -= bj_rot(a,25); \
00726 c ^= b; c -= bj_rot(b,16); \
00727 a ^= c; a -= bj_rot(c,4); \
00728 b ^= a; b -= bj_rot(a,14); \
00729 c ^= b; c -= bj_rot(b,24); \
00730 } while ( 0 )
00731
00732 #define hashlittle2( key, len, pc, pb) do { \
00733 uint32_t ext=0,a,b,c,length=(len); \
00734 union { const void *ptr; size_t i; } u; \
00735 a = b = c = 0xdeadbeef + ((uint32_t)length); \
00736 u.ptr = (void*)key; \
00737 if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { \
00738 const uint32_t *k = (const uint32_t *)(key); \
00739 while (length > 12) \
00740 { \
00741 a += k[0]; \
00742 b += k[1]; \
00743 c += k[2]; \
00744 bj_mix(a,b,c); \
00745 length -= 12; \
00746 k += 3; \
00747 } \
00748 switch(length) \
00749 { \
00750 case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; \
00751 case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; \
00752 case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; \
00753 case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; \
00754 case 8 : b+=k[1]; a+=k[0]; break; \
00755 case 7 : b+=k[1]&0xffffff; a+=k[0]; break; \
00756 case 6 : b+=k[1]&0xffff; a+=k[0]; break; \
00757 case 5 : b+=k[1]&0xff; a+=k[0]; break; \
00758 case 4 : a+=k[0]; break; \
00759 case 3 : a+=k[0]&0xffffff; break; \
00760 case 2 : a+=k[0]&0xffff; break; \
00761 case 1 : a+=k[0]&0xff; break; \
00762 case 0 : memcpy(&(pc),&c,sizeof(c)); \
00763 memcpy(&(pb),&b,sizeof(b)); \
00764 ext = 1; \
00765 } \
00766 if ( ext ) break; \
00767 } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { \
00768 const uint16_t *k = (const uint16_t *)(key); \
00769 const uint8_t *k8; \
00770 while (length > 12) \
00771 { \
00772 a += k[0] + (((uint32_t)k[1])<<16); \
00773 b += k[2] + (((uint32_t)k[3])<<16); \
00774 c += k[4] + (((uint32_t)k[5])<<16); \
00775 bj_mix(a,b,c); \
00776 length -= 12; \
00777 k += 6; \
00778 } \
00779 k8 = (const uint8_t *)k; \
00780 switch(length) \
00781 { \
00782 case 12: c+=k[4]+(((uint32_t)k[5])<<16); \
00783 b+=k[2]+(((uint32_t)k[3])<<16); \
00784 a+=k[0]+(((uint32_t)k[1])<<16); \
00785 break; \
00786 case 11: c+=((uint32_t)k8[10])<<16; \
00787 case 10: c+=k[4]; \
00788 b+=k[2]+(((uint32_t)k[3])<<16); \
00789 a+=k[0]+(((uint32_t)k[1])<<16); \
00790 break; \
00791 case 9 : c+=k8[8]; \
00792 case 8 : b+=k[2]+(((uint32_t)k[3])<<16); \
00793 a+=k[0]+(((uint32_t)k[1])<<16); \
00794 break; \
00795 case 7 : b+=((uint32_t)k8[6])<<16; \
00796 case 6 : b+=k[2]; \
00797 a+=k[0]+(((uint32_t)k[1])<<16); \
00798 break; \
00799 case 5 : b+=k8[4]; \
00800 case 4 : a+=k[0]+(((uint32_t)k[1])<<16); \
00801 break; \
00802 case 3 : a+=((uint32_t)k8[2])<<16; \
00803 case 2 : a+=k[0]; \
00804 break; \
00805 case 1 : a+=k8[0]; \
00806 break; \
00807 case 0 : memcpy(&(pc),&c,sizeof(c)); \
00808 memcpy(&(pb),&b,sizeof(b)); \
00809 ext = 1; \
00810 } \
00811 if ( ext ) break; \
00812 } else { \
00813 const uint8_t *k = (const uint8_t *)(key); \
00814 while (length > 12) \
00815 { \
00816 a += k[0]; \
00817 a += ((uint32_t)k[1])<<8; \
00818 a += ((uint32_t)k[2])<<16; \
00819 a += ((uint32_t)k[3])<<24; \
00820 b += k[4]; \
00821 b += ((uint32_t)k[5])<<8; \
00822 b += ((uint32_t)k[6])<<16; \
00823 b += ((uint32_t)k[7])<<24; \
00824 c += k[8]; \
00825 c += ((uint32_t)k[9])<<8; \
00826 c += ((uint32_t)k[10])<<16; \
00827 c += ((uint32_t)k[11])<<24; \
00828 bj_mix(a,b,c); \
00829 length -= 12; \
00830 k += 12; \
00831 } \
00832 switch(length) \
00833 { \
00834 case 12: c+=((uint32_t)k[11])<<24; \
00835 case 11: c+=((uint32_t)k[10])<<16; \
00836 case 10: c+=((uint32_t)k[9])<<8; \
00837 case 9 : c+=k[8]; \
00838 case 8 : b+=((uint32_t)k[7])<<24; \
00839 case 7 : b+=((uint32_t)k[6])<<16; \
00840 case 6 : b+=((uint32_t)k[5])<<8; \
00841 case 5 : b+=k[4]; \
00842 case 4 : a+=((uint32_t)k[3])<<24; \
00843 case 3 : a+=((uint32_t)k[2])<<16; \
00844 case 2 : a+=((uint32_t)k[1])<<8; \
00845 case 1 : a+=k[0]; \
00846 break; \
00847 case 0 : memcpy(&(pc),&c,sizeof(c)); \
00848 memcpy(&(pb),&b,sizeof(b)); \
00849 ext = 1; \
00850 } \
00851 if ( ext ) break; \
00852 } \
00853 bj_final(a,b,c); \
00854 memcpy(&(pc),&c,sizeof(c)); \
00855 memcpy(&(pb),&b,sizeof(b)); \
00856 } while (0)
00857
00858
00859
00860
00861
00862
00863 #define __hash_init( h, log2buckets ) do { \
00864 unsigned int i; \
00865 (h) = malloc( sizeof( *(h) ) ); \
00866 (h)->h.count = log2buckets>32?32:log2buckets; \
00867 (h)->h.out = __HLIST_OUTPUT; \
00868 (h)->h.hname = NULL; \
00869 (h)->data = malloc( (1<<(h)->h.count)*sizeof(struct cell_t) ); \
00870 for ( i= 0; i< (1<<(h)->h.count); i++ ) list_init( (h)->data[i] ); \
00871 } while ( 0 )
00872
00873
00874 #define __hash_set_output( l, file ) do { \
00875 fprintf( stderr, "Warning: Changing output!\n" ); \
00876 (h)->h.out = (file); \
00877 } while( 0 )
00878
00879
00880 #define __hash_set_name( h, newname ) do { \
00881 unsigned int i, len; \
00882 len = strlen(newname)+1<__HLIST_MAXLEN?strlen(newname):__HLIST_MAXLEN; \
00883 if ( (h)->h.hname ) \
00884 { \
00885 fprintf( stderr, "Warning: Changing name!\n" ); \
00886 free( (h)->h.hname ); \
00887 } \
00888 (h)->h.hname = malloc( (1+strlen(newname))*sizeof(char) ); \
00889 for ( i= 0; i< len; i++ ) (h)->h.hname[i] = newname[i]; \
00890 (h)->h.hname[i] = '\0'; \
00891 } while ( 0 ) \
00892
00893
00894 #define __hash_delete( h ) do { \
00895 unsigned int i; \
00896 for ( i= 0; i< (1<<(h)->h.count); i++ ) \
00897 list_delete( (h)->data[i] ); \
00898 if ( (h)->h.hname ) free( (h)->h.hname ); \
00899 free( h ); \
00900 } while ( 0 )
00901
00902
00903 #define __hash_print( h ) do { \
00904 unsigned int i; \
00905 if ( (h)->h.hname ) \
00906 fprintf( (h)->h.out, "Hash %s @ %p ", (h)->h.hname, (void*)(h) ); \
00907 else \
00908 fprintf( (h)->h.out, "Hash @ %p ", (void*)(h) ); \
00909 fprintf( (h)->h.out, "(%d buckets)\n", (1<<(h)->h.count) ); \
00910 for ( i= 0; i< (1<<(h)->h.count); i++ ) \
00911 list_print( (h)->data[i] ); \
00912 } while ( 0 )
00913
00914
00915 #define __hash_bytes( data, start, len, h ) do { \
00916 unsigned int h2; \
00917 hashlittle2( (((char*)data)+start), len, h, h2 ); \
00918 } while ( 0 )
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 #define __hash_fit( h, hash ) do { \
00935 unsigned int hfit = hash & ( (1<<(h)->h.count)-1 ); \
00936 memcpy( &hash, &hfit, sizeof(hash) ); \
00937 } while ( 0 )
00938
00939
00940 #define __hash_object( object, hash ) __hash_bytes( &(object), 0, sizeof(object), hash )
00941
00942
00943 #define __hash_from_key( object, key, hash ) __hash_bytes( &((object).key), (((char*)&((object).key))-((char*)&(object))), sizeof((object).key), hash )
00944
00945
00946 #define __hash_insert_object( h, object ) do { \
00947 unsigned int hash=0; \
00948 __hash_object( object, hash ); \
00949 __hash_fit( h, hash ); \
00950 list_add_first( (h)->data[hash], object ); \
00951 } while ( 0 )
00952
00953
00954 #define __hash_remove_object( h, object ) do { \
00955 unsigned int hash=0; \
00956 __hash_object( object, hash ); \
00957 __hash_fit( h, hash ); \
00958 list_del_all_object((h)->data[hash],object); \
00959 } while ( 0 )
00960
00961
00962
00963
00964 #define __hash_lookup_object( h, object, found ) do { \
00965 unsigned int hash=0; \
00966 __hash_object( object, hash ); \
00967 __hash_fit( h, hash ); \
00968 list_contains((h)->data[hash],object,found); \
00969 } while ( 0 )
00970
00971
00972 #define __hash_insert_from_key( h, object, key ) do { \
00973 unsigned int hash=0; \
00974 __hash_from_key( object, key, hash ); \
00975 __hash_fit( h, hash ); \
00976 list_add_first( (h)->data[hash], object ); \
00977 } while ( 0 )
00978
00979
00980 #define __hash_remove_from_key( h, object, key ) do { \
00981 unsigned int hash=0; \
00982 __hash_from_key( object, key, hash ); \
00983 __hash_fit( h, hash ); \
00984 list_del_all_object((h)->data[hash],object); \
00985 } while ( 0 )
00986
00987
00988
00989
00990 #define __hash_lookup_from_key( h, object, key, found ) do { \
00991 unsigned int hash=0; \
00992 __hash_from_key( object, key, hash ); \
00993 __hash_fit( h, hash ); \
00994 list_contains((h)->data[hash],object,found); \
00995 } while ( 0 )
00996
00997
00998
00999 #define hash_init(h, l2b) __hash_init(h, l2b)
01000 #define hash_set_name(h,name) __hash_set_name(h,name)
01001 #define hash_set_output(h,out) __hash_set_name(h,out)
01002 #define hash_print(h) __hash_print(h)
01003 #define hash_insert_object(h,object) __hash_insert_object(h,object)
01004 #define hash_remove_object(h,object) __hash_remove_object(h,object)
01005 #define hash_lookup_object(h,object,found) __hash_lookup_object(h,object,found)
01006 #define hash_insert_from_key(h,object,key) __hash_insert_from_key(h,object,key)
01007 #define hash_remove_from_key(h,object,key) __hash_remove_from_key(h,object,key)
01008 #define hash_lookup_from_key(h,object,key,found) __hash_lookup_from_key(h,object,key,found)
01009 #define hash_delete(h) __hash_delete(h)
01010
01011 #endif