mhash.h
typedef struct node{
unsigned char strkey[48];
void *pdata;
struct node *next;
}node;
typedef struct hashtable{
struct node * head;
int count;
pthread_spinlock_t lock;
}hashtable;
#define ERROR_SUCCESS 0
#define ERROR_FAIL 1
#define IN
#define OUT
#define HASHSIZE 1024
void inithashtab(struct hashtable** ppasthashtab, int htsize);
int hashset(struct hashtable** ppasthashtab, unsigned int size, char *key, int idatalen, void * pdata);
int hashget(struct hashtable** ppasthashtab, unsigned int size, char *key, int idatalen, OUT void * pdata);
mhash.c
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mhash.h"
void inithashtab(struct hashtable** ppasthashtab, int htsize){
int i;
hashtable* pht;
for(i=0;i<htsize;i++)
{
pht = malloc(sizeof(struct hashtable));
if (NULL != pht)
{
pht->head = NULL;
pht->count = 0;
pthread_spin_init(&pht->lock, 0);
ppasthashtab[i] = pht;
}
else
{
printf("%s line:%d exit", __func__, __LINE__);
exit(-1);
}
}
return;
}
unsigned int gethashindex(char *key, unsigned int size){
unsigned int h=0;
for(;*key;key++)
h=*key+h*10;
return h%size;
}
int hashset(struct hashtable** ppasthashtab, unsigned int size, char *key, int idatalen, void * pdata){
unsigned int hi=gethashindex(key, size);
struct hashtable* pht = ppasthashtab[hi];
struct node *np = pht->head;
struct node *plast = NULL;
void *pd;
int iret = ERROR_FAIL;
char cflag = 0;
pthread_spin_lock(&pht->lock);
/* try modify exit node */
for(; np!=NULL; np=np->next){
plast = np;
if(0 == strcmp(np->strkey, key))
{
memcpy(np->pdata, pdata, idatalen);
iret = ERROR_SUCCESS;
cflag = 1;
break;
}
}
if ( 1 != cflag)
{
/* add new node */
struct node* pnode = malloc(sizeof(struct node));
if (NULL != pnode)
{
pnode->next = NULL;
pd = malloc(idatalen);
if (NULL != pd)
{
memcpy(pd, pdata, idatalen);
pnode->pdata = pd;
if (NULL == pht->head)
pht->head = pnode;
else
plast->next = pnode;
pht->count ++;
}
else
{
free(pnode);
}
}
}
pthread_spin_unlock(&pht->lock);
return iret;
}
int hashget(struct hashtable** ppasthashtab, unsigned int size, char *key, int idatalen, OUT void * pdata){
unsigned int hi=gethashindex(key, size);
struct hashtable* pht=ppasthashtab[hi];
node *np = pht->head;
int iret = ERROR_FAIL;
pthread_spin_lock(&pht->lock);
for(; np!=NULL; np=np->next){
if(!strcmp(np->strkey, key))
{
memcpy(pdata, np->pdata, idatalen);
iret = ERROR_SUCCESS;
}
}
pthread_spin_unlock(&pht->lock);
return iret;
}
main.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mhash.h"
typedef struct nodedata{
int iData;
}nodedata;
struct hashtable* g_pastHashtab[HASHSIZE];
void main()
{
char key[32];
struct nodedata stdata;
int i;
struct hashtable * ht;
inithashtab(g_pastHashtab, HASHSIZE);
for(i = 0; i < HASHSIZE*5; i++)
{
snprintf(key, 32, "%d", i);
stdata.iData = i;
hashset(g_pastHashtab, HASHSIZE, key, sizeof(struct nodedata), &stdata);
}
for(i = 0; i < HASHSIZE; i++)
{
ht = g_pastHashtab[i];
printf("%d: %d\n", i, ht->count);
}
return;
}