代码拉取完成,页面将自动刷新
//
// Created by AnKun on 2019/12/3.
//
#include "HashMap.h"
static Entry *newEntry(void);
static HashTable *newHashTable(uint32_t size);
static HashMap *newHashMap(uint32_t size);
static void deleteEntry(Entry *entry);
static void deleteHashTable(HashTable *hashTable);
static void deleteHashMap(HashMap *hashMap);
static uint32_t HashMap_HashCode(const HashMap *const hashMap, const void *key);
static bool HashMap_Equal(const void *key1, const void *key2);
Entry *newEntry(void)
{
Entry *entry = NULL;
if ((entry = hmalloc(sizeof(Entry))) != NULL)
{
hmemset(entry->key, 0, sizeof(KEY_MAX_LEN));
hmemset(entry->value, 0, sizeof(VAL_MAX_LEN));
entry->node.next = NULL;
entry->node.prev = NULL;
}
return entry;
}
void deleteEntry(Entry *entry)
{
hfree(entry);
entry = NULL;
}
HashTable *newHashTable(uint32_t size)
{
uint32_t i = 0;
HashTable *hashTable = NULL;
if ((hashTable = hmalloc(sizeof(HashTable) * size)) != NULL)
{
for (i = 0; i != size; i++)
{
INIT_LIST_HEAD(&hashTable[i]); // 初始化链表
}
}
return hashTable;
}
void deleteHashTable(HashTable *hashTable)
{
hfree(hashTable);
hashTable = NULL;
}
HashMap *newHashMap(uint32_t size)
{
HashMap *hashMap = NULL;
if ((hashMap = hmalloc(sizeof(HashMap))) != NULL)
{
hashMap->size = size;
hashMap->used = 0;
hashMap->items = newHashTable(hashMap->size);
if (!hashMap->items)
{
hfree(hashMap);
hashMap = NULL;
}
}
return hashMap;
}
void deleteHashMap(HashMap *hashMap)
{
HashMap_Clear(hashMap); // 清空列表项
deleteHashTable(hashMap->items); // 释放哈希列表空间
hfree(hashMap); // 释放哈希表
hashMap = NULL;
}
uint32_t HashMap_HashCode(const HashMap *const hashMap, const void *key)
{
uint8_t *k = (uint8_t *) key;
unsigned long h = 0;
while (*k)
{
h = (h << 4) + *k++;
unsigned long g = h & 0xF0000000UL;
if (g)
{
h ^= g >> 24;
}
h &= ~g;
}
return h % hashMap->size;
}
bool HashMap_Put(HashMap *hashMap, const void *key, const void *value)
{
uint32_t index = 0;
Entry *entry = NULL;
Entry *iterator = NULL;
HashTable *hashTable = NULL;
// 空间不足
if (hashMap->used >= hashMap->size)
return false;
// key超长
if (strlen((const char *) key) > KEY_MAX_LEN)
return false;
// value超长
if (strlen((const char *) value) > VAL_MAX_LEN)
return false;
// 申请内存失败直接返回
if ((entry = newEntry()) == NULL)
return false;
// 拷贝到entry中
strcpy((char *) entry->key, key);
strcpy((char *) entry->value, value);
// 计算哈希值获得索引
index = HashMap_HashCode(hashMap, entry->key);
// 通过索引定位哈希列表
hashTable = &hashMap->items[index];
if (!list_empty(hashTable))
{
list_for_each_entry(iterator, hashTable, node)
{
bool isKeyExists = HashMap_Equal(iterator->key, entry->key);
bool isValueExists = HashMap_Equal(iterator->value, entry->value);
if (!isKeyExists) // 键不同
{
list_add_tail(&entry->node, hashTable);
return true;
}
else if (isKeyExists && !isValueExists) // 键相同,值不同,直接覆盖
{
hmemcpy(iterator->value, entry->value, VAL_MAX_LEN);
deleteEntry(entry);
return true;
}
else if (isKeyExists && isValueExists) // 键与值完全一致
{
deleteEntry(entry);
return true;
}
}
}
list_add_tail(&entry->node, hashTable);
hashMap->used++;
return true;
}
void *HashMap_Get(const HashMap *const hashMap, const void *key)
{
uint32_t index = 0xFFFFFFFF;
Entry *iterator = NULL;
HashTable *hashTable = NULL;
// 哈希函数计算索引
index = HashMap_HashCode(hashMap, key);
// 根据索引拿到哈希链表
hashTable = &hashMap->items[index];
// 检测并遍历取对应键的值
if (!list_empty(hashTable))
{
list_for_each_entry(iterator, hashTable, node)
{
if (HashMap_Equal(iterator->key, key))
{
return (void *) iterator->value;
}
}
}
return NULL;
}
bool HashMap_Equal(const void *key1, const void *key2)
{
return strcmp((const char *) key1, (const char *) key2) == 0 ? true : false;
}
void HashMap_Clear(HashMap *hashMap)
{
uint32_t i = 0;
Entry *entry = NULL;
if (hashMap->used != 0)
{
for (i = 0; i != hashMap->size; i++)
{
while (!list_empty(&hashMap->items[i]))
{
entry = list_first_entry(&hashMap->items[i], Entry, node);
list_del(&entry->node);
deleteEntry(entry);
}
}
hashMap->used = 0;
}
}
bool HashMap_Exists(const HashMap *const hashMap, const void *key)
{
uint32_t index = 0xFFFFFFFF;
Entry *iterator = NULL;
HashTable *hashTable = NULL;
// 计算哈希值得到索引
index = HashMap_HashCode(hashMap, key);
// 根据索引定位哈希列表
hashTable = &hashMap->items[index];
// 遍历查询
list_for_each_entry(iterator, hashTable, node)
{
if (HashMap_Equal(iterator->key, key))
return true;
}
return false;
}
void HashMap_Remove(HashMap *hashMap, const void *key)
{
uint32_t index = 0xFFFFFFFF;
HashTable *hashTable = NULL;
Entry *entry = NULL;
// 计算哈希值获得索引
index = HashMap_HashCode(hashMap, key);
// 根据索引得到哈希列表
hashTable = &hashMap->items[index];
// 遍历查找并删除
while (!list_empty(hashTable))
{
entry = list_first_entry(hashTable, Entry, node);
if (HashMap_Equal(entry->key, key))
{
list_del(&entry->node);
deleteEntry(entry);
hashMap->used--;
break;
}
}
}
HashMap *HashMap_Create(uint32_t size)
{
return newHashMap(size);
}
void HashMap_Destroy(HashMap *hashMap)
{
deleteHashMap(hashMap);
}
void HashMap_GetKeys(const HashMap *const hashMap, uint8_t **keys, uint32_t *count)
{
uint32_t i = 0;
HashTable *hashTable = NULL;
*count = 0;
for (i = 0; i != hashMap->size; i++)
{
hashTable = &hashMap->items[i];
if (!list_empty(hashTable))
{
Entry *iterator = NULL;
list_for_each_entry(iterator, hashTable, node)
{
keys[(*count)++] = iterator->key;
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。