#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 0X10
struct_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;
}
哈希表实现
最新推荐文章于 2020-01-23 09:19:00 发布