哈希表实现

来源:互联网 发布:mac卸载google chrome 编辑:程序博客网 时间:2024/06/04 19:14
#include <stdlib.h>#include <stdio.h>#include <string.h>typedef struct _struct_hash_key{    unsigned int uiIp;    unsigned int uiTeid;} struct_hash_key;typedef struct _struct_hash_node{    struct _struct_hash_node *pstNext;    struct _struct_hash_key stKey;    unsigned long long u64_timeout;} struct_hash_node;typedef struct _struct_bucket{    unsigned int uiBucketLen;    struct _node *pstHead;} struct_bucket;typedef struct _struct_hash_table{    unsigned int uiNode;    unsigned int uiBucketNum;    unsigned int uiNodeCount;    unsigned int uiAgingBucket;    struct_bucket *pstHashTable;    struct_hash_node *pstFreeHead;    struct_hash_node *pstFreeTail;} struct_hash_table;#define clock_xxx_is_timeout(current_clock, timeout_clock) (current_clock > timeout_clock)#define SYS_PARAM_BUCKET_NUM 0X10struct_hash_table *g_pst_table = NULL;static unsigned int get_hash_value(struct_hash_table *pstTable, const struct_hash_key *pstKey){    unsigned int uiHash;    uiHash = (pstKey->uiIp + pstKey->uiTeid) % pstTable->uiBucketNum;    return uiHash;}static unsigned int compare(const struct_hash_key *pstKey, const struct_hash_key *pstKeyHash){    if (pstKey->uiIp == pstKeyHash->uiIp && pstKey->uiTeid == pstKeyHash->uiTeid)    {        return 1;    }    return 0;}struct_hash_table *create_hash_table(unsigned int uiBucketNum, unsigned int uiNodeNum){    unsigned long long u64_mem_count;    int i;    struct_hash_table *pstTable;    if (0 == uiBucketNum || 0 == uiNodeNum)    {        printf("0 bucketNum or node num error!!\n");    }    u64_mem_count = sizeof(struct_hash_table) +         sizeof(struct_bucket) * uiBucketNum +        sizeof(struct_hash_node) * uiNodeNum;    pstTable = (struct_hash_table *)malloc(u64_mem_count);    pstTable->pstHashTable = (struct_bucket *)(void *)&pstTable[1];    pstTable->pstFreeHead = (struct_hash_node *)&pstTable->pstHashTable[uiBucketNum];    memset(pstTable->pstFreeHead, 0, sizeof(struct_hash_node) * uiNodeNum);    for (i = 0; i < uiNodeNum -1; i++)    {        pstTable->pstFreeHead[i].pstNext = &pstTable->pstFreeHead[i + 1];    }    pstTable->pstFreeTail = &pstTable->pstFreeHead[uiNodeNum -1];    pstTable->pstFreeTail->pstNext = NULL;    pstTable->uiBucketNum = uiBucketNum;    pstTable->uiNodeCount = uiNodeNum;    pstTable->uiAgingBucket = 0;    return pstTable;}struct_hash_node *add_hash_key(struct_hash_table *pstTable, const struct_hash_key *pstKey){    unsigned int uiHashIndex;    struct_hash_node *pstNode;    pstNode = pstTable->pstFreeHead;    if (NULL == pstNode)    {        return NULL;    }    pstTable->pstFreeHead = pstTable->pstFreeHead->pstNext;    if (NULL == pstTable->pstFreeHead)    {        pstTable->pstFreeTail = NULL;    }    pstNode->stKey.uiIp = pstKey->uiIp;    pstNode->stKey.uiTeid = pstKey->uiTeid;    uiHashIndex = get_hash_value(pstTable, pstKey);    pstNode->pstNext = pstTable->pstHashTable[uiHashIndex].pstHead;    pstNode->u64_timeout = 0;    pstTable->pstHashTable[uiHashIndex].pstHead = pstNode;    pstTable->pstHashTable[uiHashIndex].uiBucketLen++;    pstTable->uiNodeCount++;    return pstNode;}struct_hash_node * find_hash_node(struct_hash_table *pstTable, const struct_hash_key *pstKey){    unsigned int uiHashIndex;    struct_hash_node *pstNode = NULL;    uiHashIndex = get_hash_value(pstTable, pstKey);    pstNode = pstTable->pstHashTable[uiHashIndex].pstHead;    while (NULL != pstNode)    {        if (compare(pstKey, &pstNode->stKey))        {            break;        }        pstNode = pstNode->pstNext;    }    return pstNode;}void delete_hash_node(struct_hash_table *pstTable, struct_hash_node *pstNode){    unsigned uiHashIndex;    struct_hash_node *pstNodeCur = NULL;    struct_hash_node *pstNodePre = NULL;    uiHashIndex = get_hash_value(pstTable, &pstNode->stKey);    pstNodeCur = pstTable->pstHashTable[uiHashIndex].pstHead;    if (NULL == pstNodeCur)    {        return;    }    if (pstNodeCur == pstNode)    {        pstTable->pstHashTable[uiHashIndex].pstHead = pstNode->pstNext;    }    else    {        pstNodePre = pstTable->pstHashTable[uiHashIndex].pstHead;        pstNodeCur = pstNodePre->pstNext;        while (NULL != pstNodeCur)        {            if (pstNodeCur == pstNode)            {                pstNodePre->pstNext = pstNode->pstNext;                break;            }            pstNodePre = pstNodeCur;            pstNodeCur = pstNodeCur->pstNext;        }    }    memset(pstNode, 0, sizeof(struct_hash_node));    if ((NULL == pstTable->pstFreeTail && NULL == pstTable->pstFreeHead))    {        pstTable->pstFreeHead = pstNode;        pstTable->pstFreeTail = pstNode;    }    else    {        pstTable->pstFreeTail->pstNext = pstNode;        pstTable->pstFreeTail = pstNode;    }    return;}void aging(struct_hash_table *pstTable, unsigned int u32_max_buckets,        unsigned long long u64_timeout){    if (NULL == pstTable)    {        return;    }    if (0 == pstTable->uiNodeCount)    {        return;    }    unsigned int uiHashIndex;    unsigned int u32_loop_for_bucket_count = 0;    for (uiHashIndex = pstTable->uiAgingBucket; uiHashIndex < SYS_PARAM_BUCKET_NUM; uiHashIndex++)    {        struct_hash_node *pstNodeCur = pstTable->pstHashTable[uiHashIndex].pstHead;        struct_hash_node *pstNodePre = pstTable->pstHashTable[uiHashIndex].pstHead;        while (NULL != pstNodeCur)        {            if (clock_xxx_is_timeout(u64_timeout, pstNodeCur->u64_timeout))            {                struct_hash_node *pstNodeNext = pstNodeCur->pstNext;                if (pstNodeCur == pstTable->pstHashTable[uiHashIndex].pstHead)                {                    pstTable->pstHashTable[uiHashIndex].pstHead = pstNodeCur->pstNext;                }                else                {                    pstNodePre->pstNext = pstNodeCur->pstNext;                }                memset(pstNodeCur, 0, sizeof(struct_hash_node));                if (NULL == pstTable->pstFreeHead && NULL == pstTable->pstFreeHead)                {                    pstTable->pstFreeHead = pstNodeCur;                    pstTable->pstFreeTail = pstNodeCur;                }                else                {                    pstTable->pstFreeTail->pstNext = pstNodeCur;                    pstTable->pstFreeTail = pstNodeCur;                }                pstNodeCur = pstNodeNext;            }            else            {                pstNodePre = pstNodeCur;                pstNodeCur = pstNodeCur->pstNext;            }        }        u32_loop_for_bucket_count++;        pstTable->uiAgingBucket++;        if (pstTable->uiAgingBucket >= pstTable->uiBucketNum)        {            pstTable->uiAgingBucket = 0;        }        if (u32_loop_for_bucket_count >= u32_max_buckets)        {            break;        }    }    return;}int main(void){    unsigned int uiBucketNum = 10;    unsigned int uiNodeNum = 100;    struct_hash_node *pstNode = NULL;    struct_hash_key  stKey;    stKey.uiIp = 0xffffffff;    stKey.uiTeid = 0x12345678;    g_pst_table = create_hash_table(uiBucketNum, uiNodeNum);    add_hash_key(g_pst_table, &stKey);    pstNode = find_hash_node(g_pst_table, &stKey);    if (NULL == pstNode)    {        printf("The node has been found\n");    }    delete_hash_node(g_pst_table, pstNode);    pstNode = find_hash_node(g_pst_table, &stKey);    if (NULL == pstNode)    {        printf("The node hash been deleted!!\n");    }    add_hash_key(g_pst_table, &stKey);    aging(g_pst_table, 10, 0xffffffff);    pstNode = find_hash_node(g_pst_table, &stKey);    if (NULL == pstNode)    {        printf("Aging successfully!!\n");    }    free(g_pst_table);    return 0;}

0 0