📄 sfghash.c
字号:
SFGHASH_NODE * hnode; hnode = sfghash_find_node( t, key ); if( hnode ) return hnode->data; return NULL;}/** Unlink and free the node*/static int sfghash_free_node( SFGHASH * t, unsigned index, SFGHASH_NODE * hnode ){ if( !t->userkey && hnode->key ) s_free( hnode->key ); hnode->key = 0; if( t->userfree && hnode->data ) t->userfree( hnode->data ); /* free users data, with users function */ if( hnode->prev ) // not the 1st node { hnode->prev->next = hnode->next; if( hnode->next ) hnode->next->prev = hnode->prev; } else if( t->table[index] ) // 1st node { t->table[index] = t->table[index]->next; if( t->table[index] )t->table[index]->prev = 0; } s_free( hnode ); t->count--; return SFGHASH_OK;}/** Remove a Key/Data Pair from the table - find it, unlink it, and free the memory for it.** returns : 0 - OK* -1 - node not found*/int sfghash_remove( SFGHASH * t, void * key){ SFGHASH_NODE * hnode; int klen; unsigned hashkey, index; if( t->keysize > 0 ) { klen = t->keysize; } else { klen = strlen((char*)key) + 1; } hashkey = t->sfhashfcn->hash_fcn( t->sfhashfcn, (unsigned char*) key, klen ); index = hashkey % t->nrows; for( hnode=t->table[index]; hnode; hnode=hnode->next ) { if( t->keysize > 0 ) { if( !t->sfhashfcn->keycmp_fcn(hnode->key,key,klen) ) { return sfghash_free_node( t, index, hnode ); } } else { if( !strcmp((const char *)hnode->key,(const char*)key) ) { return sfghash_free_node( t, index, hnode ); } } } return SFGHASH_ERR; }/***/int sfdict_remove( SFGHASH * t, char * key){ return sfghash_remove( t, key);}/** Get First Hash Table Node*/SFGHASH_NODE * sfghash_findfirst1( SFGHASH * t ){ /* Start with 1st row */ for( t->crow=0; t->crow < t->nrows; t->crow++ ) { /* Get 1st Non-Null node in row list */ t->cnode = t->table[t->crow]; if( t->cnode ) return t->cnode; } return NULL;}/** Get Next Hash Table Node*/SFGHASH_NODE * sfghash_findnext1( SFGHASH * t ){ if( t->cnode ) /* get next in this list */ { /* Next node in current node list */ t->cnode = t->cnode->next; if( t->cnode ) { return t->cnode; } } /* Get 1st node in next non-emtoy row/node list */ for( t->crow++; t->crow < t->nrows; t->crow++ ) { t->cnode = t->table[ t->crow ]; if( t->cnode ) { return t->cnode; } } return NULL;}/* Internal use only */static void sfghash_next( SFGHASH * t ){ if( !t->cnode ) return ; /* Next node in current node list */ t->cnode = t->cnode->next; if( t->cnode ) { return; } /* Next row */ /* Get 1st node in next non-emtoy row/node list */ for( t->crow++; t->crow < t->nrows; t->crow++ ) { t->cnode = t->table[ t->crow ]; if( t->cnode ) { return; } }}/** Get First Hash Table Node*/SFGHASH_NODE * sfghash_findfirst( SFGHASH * t ){ SFGHASH_NODE * n; /* Start with 1st row */ for( t->crow=0; t->crow < t->nrows; t->crow++ ) { /* Get 1st Non-Null node in row list */ t->cnode = t->table[ t->crow ]; if( t->cnode ) { n = t->cnode; sfghash_next( t ); // load t->cnode with the next entry return n; } } return NULL;}/** Get Next Hash Table Node*/SFGHASH_NODE * sfghash_findnext( SFGHASH * t ){ SFGHASH_NODE * n; n = t->cnode; if( !n ) /* Done, no more entries */ { return NULL; } /* Preload next node into current node */ sfghash_next( t ); return n;}/**** ATOM SUPPORT - A Global String+DataPtr Hash Table** Data Pointers are not free'd automatically, the user* must do this.*//** */static SFGHASH * g_atom=0; /* atom hash table */static int atom_first=1; /* supports auto init on 1st add_atom call */static int natoms=1000; /* # rows in hash table - more makes it faster access *//** set size of atom hash table*/int sfatom_setsize( int n ){ natoms = n; return 0;}/** */int sfatom_init(){ if( !atom_first ) return 0; /* Create a Hash Table */ g_atom = sfghash_new( natoms, 0 /* string keys */, GH_COPYKEYS, NULL /* User frees data */ ); if( !g_atom ) { return SFGHASH_ERR; } atom_first = 0; return SFGHASH_OK;}/***/int sfatom_reset(){ atom_first = 1; sfghash_delete( g_atom ); if( sfatom_init() ) { return SFGHASH_ERR; } return SFGHASH_OK;}/***/int sfatom_add(char * str, void * data){ if( atom_first ) { if( sfatom_init() ) { return SFGHASH_ERR; } } if( !g_atom ) { return SFGHASH_ERR; } sfghash_add( g_atom, strdup(str), data ); return SFGHASH_OK;}/***/int sfatom_remove(char * str){ return sfghash_remove( g_atom, str );}/***/void * sfatom_find(char * str){ return (void*) sfghash_find( g_atom, str );}/***/int sfatom_count(){ return g_atom->count;}/***/SFGHASH_NODE * sfatom_findfirst(){ SFGHASH_NODE * node = sfghash_findfirst( g_atom ); if( node ) return node; return NULL;}/***/SFGHASH_NODE * sfatom_findnext(){ SFGHASH_NODE * node = sfghash_findnext( g_atom ); if( node ) return node; return NULL;}/*** Test Driver for Hashing* */#ifdef SFGHASH_MAIN void myfree ( void * p ){ printf("freeing '%s'\n",p); free(p);}/** Hash test program */int main ( int argc, char ** argv ){ int i; SFGHASH * t; SFGHASH_NODE * n, *m; char str[256],*p; int num=100; if( argc > 1 ) num = atoi(argv[1]); sfatom_init(); /* Create a Hash Table */ t = sfghash_new( 1000, 0 , GH_COPYKEYS , myfree ); /* Add Nodes to the Hash Table */ for(i=0;i<num;i++) { sprintf(str,"KeyWord%d",i+1); sfghash_add( t, str, strupr(strdup(str)) ); sfatom_add( str, strupr(strdup(str)) ); } /* Find and Display Nodes in the Hash Table */ printf("\n** FIND KEY TEST\n"); for(i=0;i<num;i++) { sprintf(str,"KeyWord%d",i+1); p = (char*) sfghash_find( t, str ); printf("Hash-key=%*s, data=%*s\n", strlen(str),str, strlen(str), p ); p = (char*) sfatom_find( str ); printf("Atom-key=%*s, data=%*s\n", strlen(str),str, strlen(str), p ); } /* Display All Nodes in the Hash Table */ printf("\n** FINDFIRST / FINDNEXT TEST\n"); for( n = sfghash_findfirst(t); n; n = sfghash_findnext(t) ) { printf("hash-findfirst/next: key=%s, data=%s\n", n->key, n->data ); // hashing code frees user data using 'myfree' above .... if( sfghash_remove(t,n->key) ) printf("Could not remove the key node\n"); else printf("key node removed\n"); } for( n = sfatom_findfirst(); n; n = sfatom_findnext() ) { printf("atom-findfirst/next: key=%s, data=%s\n", n->key, n->data ); free( n->data ); //since atom data is not freed automatically } /* Free the table and it's user data */ printf("****sfghash_delete\n"); sfghash_delete( t ); printf("****sfatom_reset\n"); sfatom_reset(); printf("\nnormal pgm finish\n\n"); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -