www.pudn.com > ccache.rar > hash.c


/******************************************************************** 
	created:	2008/01/24 
	filename: 	hash.c 
	author:		Lichuang 
                 
	purpose:     
*********************************************************************/ 
 
#include "hash.h" 
#include "lock.h" 
#include  
 
unsigned int hash(const void* key, ccache_t* cache) 
{ 
#define mix(a,b,c) \ 
    { \ 
        a -= b; a -= c; a ^= (c >> 13); \ 
        b -= c; b -= a; b ^= (a << 8); \ 
        c -= a; c -= b; c ^= (b >> 13); \ 
        a -= b; a -= c; a ^= (c >> 12);  \ 
        b -= c; b -= a; b ^= (a << 16); \ 
        c -= a; c -= b; c ^= (b >> 5); \ 
        a -= b; a -= c; a ^= (c >> 3);  \ 
        b -= c; b -= a; b ^= (a << 10); \ 
        c -= a; c -= b; c ^= (b >> 15); \ 
    } 
 
    char *k = (char *)key; 
    unsigned int a, b, c, i, len; 
    unsigned int length = cache->keysize; 
 
    for (i = 0; i < length; i++) 
        k[i] = tolower(k[i]); 
 
    len = length; 
    a = b = c = 0x9e3779b9;  /* the golden ratio; an arbitrary value */ 
 
    while (12 <= len) 
    { 
        a += (k[0] +((unsigned int)k[1] << 8) +((unsigned int)k[2] << 16) +((unsigned int)k[3] << 24)); 
        b += (k[4] +((unsigned int)k[5] << 8) +((unsigned int)k[6] << 16) +((unsigned int)k[7] << 24)); 
        c += (k[8] +((unsigned int)k[9] << 8) +((unsigned int)k[10]<< 16)+((unsigned int)k[11] << 24)); 
        mix(a,b,c); 
        k += 12;  
        len -= 12; 
    } 
 
    c += length; 
    switch(len)  
    { 
        case 11: c+=((unsigned int)k[10] << 24); 
        case 10: c+=((unsigned int)k[9]  << 16); 
        case 9 : c+=((unsigned int)k[8]  << 8); 
        case 8 : b+=((unsigned int)k[7] << 24); 
        case 7 : b+=((unsigned int)k[6] << 16); 
        case 6 : b+=((unsigned int)k[5] << 8); 
        case 5 : b+=k[4]; 
        case 4 : a+=((unsigned int)k[3] << 24); 
        case 3 : a+=((unsigned int)k[2] << 16); 
        case 2 : a+=((unsigned int)k[1] << 8); 
        case 1 : a+=k[0]; 
    } 
    mix(a,b,c); 
 
    return c % cache->hashitemnum; 
} 
 
int inithashitem(ccache_t* cache) 
{ 
    int hashitemnum = cache->hashitemnum; 
    int i; 
 
    hashitem_t* hashitem; 
    for (i = 0; i < hashitemnum; ++i) 
    { 
        hashitem = HASH_ITEM(cache, i); 
 
        hashitem->first = -1; 
        hashitem->nodenum = 0; 
 
       if (0 > initthreadmutex(&(hashitem->mutex))) 
            return -1; 
    } 
 
    hashitem = HASH_ITEM(cache, 0); 
 
    return 0; 
} 
 
int lockhashtable(int hashitem, ccache_t* cache) 
{ 
    hashitem_t* hash = HASH_ITEM(cache, hashitem); 
 
    int ret = lock(&(hash->mutex)); 
    return ret; 
} 
 
int unlockhashtable(int hashitem, ccache_t* cache) 
{ 
    hashitem_t* hash = HASH_ITEM(cache, hashitem); 
 
    int ret = unlock(&(hash->mutex)); 
    return ret; 
}