/* * * Create a new hash table * * nrows : number of rows in hash table, primes are best. * > 0 => we use the nearest prime internally * < 0 => we use the magnitude as nrows. * keysize : > 0 => bytes in each key, keys are binary bytes, * all keys are the same size. * ==0 => keys are strings and are null terminated, * allowing random key lengths. * userkeys : > 0 => indicates user owns the key data * and we should not allocate or free space for it, * nor should we attempt to free the user key. We just * save the pointer to the key. * ==0 => we should copy the keys and manage them internally * userfree : routine to free users data, null if we should not * free user data in sfghash_delete(). The routine * should be of the form 'void userfree(void * userdata)', * 'free' works for simple allocations. */ SFGHASH * sfghash_new( int nrows, int keysize, int userkeys, void (*userfree)(void*p) ) { int i; SFGHASH * h; if( nrows > 0 ) /* make sure we have a prime number */ { nrows = sf_nearest_prime( nrows ); } else /* use the magnitude or nrows as is */ { nrows = -nrows; } h = (SFGHASH*)s_alloc( sizeof(SFGHASH) ); if( !h ) return 0; memset( h, 0, sizeof(SFGHASH) ); h->sfhashfcn = sfhashfcn_new( nrows ); if( !h->sfhashfcn ) { free(h); return 0; } h->table = (SFGHASH_NODE**) s_alloc( sizeof(SFGHASH_NODE*) * nrows ); if( !h->table ) { free(h->sfhashfcn); free(h); return 0; } for( i=0; i<nrows; i++ ) { h->table[i] = 0; } h->userkey = userkeys; h->keysize = keysize; h->nrows = nrows; h->count = 0; h->userfree = userfree; h->crow = 0; // findfirst/next current row h->cnode = 0; // findfirst/next current node ptr return h; }
SFHASHFCN * sfhashfcn_new( int m ) { SFHASHFCN * p; static int one=1; if( one ) /* one time init */ { srand( (unsigned) time(0) ); one = 0; } // This can make all of the hashing static for testing. //#define rand() 0 p = (SFHASHFCN*) calloc( 1,sizeof(SFHASHFCN) ); if( !p ) return 0; #ifdef STATIC_HASH #ifndef DYNAMIC_PREPROC_CONTEXT if (ScStaticHash()) { sfhashfcn_static(p); } else #endif #endif { p->seed = sf_nearest_prime( (rand()%m)+3191 ); p->scale = sf_nearest_prime( (rand()%m)+709 ); p->hardener = (rand()*rand()) + 133824503; } p->hash_fcn = &sfhashfcn_hash; p->keycmp_fcn = &memcmp; return p; }