本文共 3961 字,大约阅读时间需要 13 分钟。
为什么去做这个?
在接触哈希表的实现时,大多数人习惯于使用数字来进行操作。但在实际工作中,尤其是在处理URL解析几乎是每天都会用到的场景时,我们更倾向于使用字符串。为什么选择使用哈希表来存储URL呢?
首先,在MQTT协议中,发布与订阅者之间的订阅树管理需要对URL进行解析并存储。这使得将解析后的URL存储到一个哈希表中变得非常必要。这一部分内容对理解mosquitto源码有非常大的帮助,同时也有很多实际的优化空间。
代码展示
#ifndef __HASH_H__#define __HASH_H__#include#include #include #define HASH_TABLE_SIZE 676#define URL_SIZE 128#define URL_LEN 32#define ASCII_A 161#define FRIST_BIT 0#define TWO_BIT 1typedef char DataType[URL_SIZE];typedef struct node { DataType Data; struct node *pNext;} LinkNode;#endif
#include "hash.h"LinkNode *HashTable[HASH_TABLE_SIZE] = {0};char* getKeyValue(char* url) { char* new_url = NULL; new_url = strtok(url, "/"); new_url = strtok(NULL, "/"); return new_url;}int getIdxValue(char* key) { char valuel = 0; char value2 = 0; char keykey[URL_SIZE] = {0}; int idxl = 0; if (key != NULL) { strcpy(keykey, key); valuel = keykey[FRIST_BIT]; value2 = keykey[TWO_BIT]; idxl = (valuel - 'A' + ASCII_A) + (value2 - 'A' + ASCII_A); return idxl; } return 0;}int InsertHashtable(char* url) { int len = 0; char old_url[URL_SIZE] = {0}; char* value = NULL; strcpy(old_url, url); char* key = getKeyValue(url); if (key == NULL) { return 0; } int idx = getIdxValue(key); len = strlen(key); value = strstr(old_url, key); value++; value += len; LinkNode* pInsertNode = malloc(sizeof(LinkNode)); if (pInsertNode == NULL) { perror("fail to malloc"); return -1; } strcpy(pInsertNode->Data, value); pInsertNode->pNext = NULL; LinkNode** ppTmp = &HashTable[idx]; while (ppTmp != NULL) { ppTmp = &(*ppTmp)->pNext; } pInsertNode->pNext = *ppTmp; *ppTmp = pInsertNode;}void ShowHashtable() { int i = 0; for (; i < HASH_TABLE_SIZE; i++) { if (HashTable[i] != NULL) { LinkNode* pTmpNode = HashTable[i]; while (pTmpNode != NULL) { printf("%s ", pTmpNode->Data); pTmpNode = pTmpNode->pNext; } printf("\n"); } continue; }}int FindHashtable(char* url) { int len = 0; char old_url[URL_SIZE] = {0}; char* value = NULL; strcpy(old_url, url); char* key = getKeyValue(url); if (key == NULL) { return 0; } int idx = getIdxValue(key); len = strlen(key); value = strstr(old_url, key); value++; value += len; LinkNode* pTmpNode = HashTable[idx]; while (pTmpNode != NULL) { if (!strcmp(pTmpNode->Data, value)) { printf("Found URL: %s\n", pTmpNode->Data); return 1; } pTmpNode = pTmpNode->pNext; } return 0;}void DestroyHashtable() { int i = 0; LinkNode* pFreeNode = NULL; LinkNode* pTmpNode = NULL; for (; i < HASH_TABLE_SIZE; i++) { pTmpNode = HashTable[i]; while (pTmpNode != NULL) { pFreeNode = pTmpNode; pTmpNode = pTmpNode->pNext; free(pFreeNode); } }}
#include "hash.h"char value[URL_SIZE] = {0};int i = 0;char url[URL_LEN][URL_SIZE] = { "/ISA/Syste/device", "/ISA/System/time", "/ISA/Syste/time/timeZ", "/ISA/System/upgradeFlag", "/ISA/Syste/Hardwar/capabilities", "/ISA/System/Software/capabilities", "/ISA/Syste/Vid/inputs/OSDLanguage", "/ISA/System/Video/inputs/1/overlays", "/ISA/Event/channels/capabilities", "/ISA/PTZCtrl/channels/1", "/ISA/Ctrl/channe/1/maxele/capabil", "/ISA/Image/proportionalpan", "/ISA/Image/channels/1/i", "/ISA/Security/sessionHear"};for (i = 0; i < URL_LEN; i++) { InsertHashtable(url[i]);}ShowHashtable();printf("请输入查找URL:\n");scanf("%s", value);if (!FindHashtable(value)) { printf("未找到该URL\n");}DestroyHashtable();
总结
这段代码是对新手或接触编程不多的开发者友好的实现,帮助他们更深入地理解哈希表的概念。在实现过程中,我对键值进行了双重处理,虽然达不到真正的哈希表,但仍包含了一些思想。
如果你对这部分内容感兴趣,可以继续跟我交流,这里没有首先、其次之类的句式,让我们一起讨论与提升。
转载地址:http://oooaz.baihongyu.com/