当前位置: 首页 > news >正文

静态网站是什么样网络营销的方式

静态网站是什么样,网络营销的方式,源代码代做网站,晋江网站建设公司字典也叫哈希表。看一下redis中的实现。下面是数据结构关系图。 redis中,哈希表的设计思想是,申请一个指针数组,然后每个元素指向一个链表用来存储数据(即链地址法)。 1 创建一个字典 // 申请一个表示字典的数据结构…

字典也叫哈希表。看一下redis中的实现。下面是数据结构关系图。

redis中,哈希表的设计思想是,申请一个指针数组,然后每个元素指向一个链表用来存储数据(即链地址法)。

1 创建一个字典

// 申请一个表示字典的数据结构
dict *dictCreate(dictType *type,void *privDataPtr)
{dict *ht = _dictAlloc(sizeof(*ht));_dictInit(ht,type,privDataPtr);return ht;
} // 初始化字典数据结构
int _dictInit(dict *ht, dictType *type,void *privDataPtr)
{_dictReset(ht);ht->type = type;ht->privdata = privDataPtr;return DICT_OK;
}// 扩容
int dictResize(dict *ht)
{int minimal = ht->used;if (minimal < DICT_HT_INITIAL_SIZE)minimal = DICT_HT_INITIAL_SIZE;return dictExpand(ht, minimal);
}  

首先调用申请一个dict结构体用来表示一个字典。然后初始化他的相关字段,最后调用dictExpand开辟保存数据的内存。

int dictExpand(dict *ht, unsigned long size)
{dict n; // size是数组元素的个数,需要是2的倍数unsigned long realsize = _dictNextPower(size), i;_dictInit(&n, ht->type, ht->privdata);// 哈希表数组的长度n.size = realsize;// 索引掩码,用于计算索引n.sizemask = realsize-1;// 用作哈希表的指针数组n.table = _dictAlloc(realsize*sizeof(dictEntry*));// 初始化内存为0memset(n.table, 0, realsize*sizeof(dictEntry*));// 之前字典已经使用的项数,复制过来,used是字典里节点个数n.used = ht->used;for (i = 0; i < ht->size && ht->used > 0; i++) {dictEntry *he, *nextHe;// 空项,不需要复制if (ht->table[i] == NULL) continue;he = ht->table[i];while(he) {unsigned int h;// 保存下一个节点的地址,table的每一个项都是一个链表nextHe = he->next;  /* Get the new element index */// 重新计算he的索引h = dictHashKey(ht, he->key) & n.sizemask;// 插入索引为h的字典项中,头插法he->next = n.table[h];n.table[h] = he;// 使用数减一ht->used--;he = nextHe;}}assert(ht->used == 0);// 释放旧的内存_dictFree(ht->table);// 覆盖之前的信息*ht = n;return DICT_OK;
}

这样就形成了一个和文章开始那个图一样的结构。

2 往字典加入一个元素

int dictAdd(dict *ht, void *key, void *val)
{int index;dictEntry *entry;// 计算key是否已经存在,不存在则返回key对应的索引if ((index = _dictKeyIndex(ht, key)) == -1)return DICT_ERR;// 申请一个字典项entry = _dictAlloc(sizeof(*entry));// 头插法插入第index项对应的链表中entry->next = ht->table[index];ht->table[index] = entry;// 设置键值dictSetHashKey(ht, entry, key);dictSetHashVal(ht, entry, val);// 节点数加一ht->used++;return DICT_OK;
}

1 首先判断key是否已经存在,存在的话就无法添加。
2 根据key和哈希函数,计算对应的索引。
3 头插法插入对应索引的链表。

3 修改某个key对应的值

int dictReplace(dict *ht, void *key, void *val)
{dictEntry *entry;// 尝试新增,成功说明之前还没有这个key,否则说明存在,下面再替换if (dictAdd(ht, key, val) == DICT_OK)return DICT_OK;// 找到key对应的索引entry = dictFind(ht, key);// 释放当前的valuedictFreeEntryVal(ht, entry);// 重新设置新值dictSetHashVal(ht, entry, val);return DICT_OK;
}

4 删除一个元素

static int dictGenericDelete(dict *ht, const void *key, int nofree)
{unsigned int h;dictEntry *he, *prevHe;// 空字典if (ht->size == 0)return DICT_ERR;// 算出索引h = dictHashKey(ht, key) & ht->sizemask;// 拿到索引对应的链表he = ht->table[h];prevHe = NULL;while(he) {// 比较key,找到返回trueif (dictCompareHashKeys(ht, key, he->key)) {/* Unlink the element from the list */// 上一个不匹配节点的next指针指向待删除节点的下一个节点if (prevHe)prevHe->next = he->next;else// prevHe为空,说明待删除的节点是链表的第一个节点,则更新头指针指向待删除节点的下一个ht->table[h] = he->next;// if (!nofree) {dictFreeEntryKey(ht, he);dictFreeEntryVal(ht, he);}// 删除这个节点_dictFree(he);// 已使用个数减一ht->used--;return DICT_OK;}// 保存上一个不匹配的prevHe = he;he = he->next;}return DICT_ERR; /* not found */
}

首先根据key找到索引的对应的链表,然后遍历链表找到key一样的节点,最后就是从链表中删除一个节点。
    新增和删除等操作都涉及到查找元素,我们看看怎么查找。

5 查找

dictEntry *dictFind(dict *ht, const void *key)
{dictEntry *he;unsigned int h;if (ht->size == 0) return NULL;// 自定义的哈希函数钩子h = dictHashKey(ht, key) & ht->sizemask;he = ht->table[h];while(he) {// 自定义的比较函数钩子if (dictCompareHashKeys(ht, key, he->key))return he;he = he->next;}return NULL;
}

我们可以看一下某个钩子的实现。

// 哈希函数
unsigned int dictGenHashFunction(const unsigned char *buf, int len) {unsigned int hash = 5381;while (len--)hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */return hash;
}
// 比较函数
static int _dictStringCopyHTKeyCompare(void *privdata, const void *key1,const void *key2)
{return strcmp(key1, key2) == 0;
}

总来的流程就是根据key产生一个索引,然后根据索引到哈希表中取得对应的一个链表,然后操作这个链表(新增,查找,删除)。

6 销毁字典

// 销毁整个字典
int _dictClear(dict *ht)
{unsigned long i;/* Free all the elements */for (i = 0; i < ht->size && ht->used > 0; i++) {dictEntry *he, *nextHe;// 空闲项,跳过if ((he = ht->table[i]) == NULL) continue;// while(he) {// 先保存下一个节点地址,不然下面内存被释放就找不到了nextHe = he->next;// 释放键内存dictFreeEntryKey(ht, he);// 释放值内存dictFreeEntryVal(ht, he);// 释放节点内存_dictFree(he);// 使用数减一ht->used--;he = nextHe;}}/* Free the table and the allocated cache structure */// 释放字典结构体_dictFree(ht->table);/* Re-initialize the table */// 重置字段_dictReset(ht);return DICT_OK; /* never fails */
}

该函数只是释放字典里存储数据的内存,但是没有释放字典本身。下面函数可以释放字典本身的内存。

// 释放字典里的数据和字典本身
void dictRelease(dict *ht)
{_dictClear(ht);_dictFree(ht);
}

7 迭代字典
redis中实现了各种迭代器对某种数据结构进行迭代,比如字典。

// 申请字典迭代器
dictIterator *dictGetIterator(dict *ht)
{dictIterator *iter = _dictAlloc(sizeof(*iter));iter->ht = ht;iter->index = -1;iter->entry = NULL;iter->nextEntry = NULL;return iter;
}
// 迭代字典的元素,每次调用返回一个节点
dictEntry *dictNext(dictIterator *iter)
{while (1) {// 初始化时entry为NULLif (iter->entry == NULL) {iter->index++;// 到底了才break,而不是entry为空if (iter->index >=(signed)iter->ht->size) break;// 返回索引为0对应的链表iter->entry = iter->ht->table[iter->index];} else {iter->entry = iter->nextEntry;}// 还有节点,则同时记录下一个节,返回entry节点if (iter->entry) {iter->nextEntry = iter->entry->next;return iter->entry;}}return NULL;
}

基本的逻辑就是,按照哈希表数组的索引,从小到大,每一个索引,先去遍历他对应的链表,遍历完后,继续下一个索引,直到最后一个索引结束。

总结,redis的字典里还有其他的一些方法,没有一一列举。有兴趣可以点这。

http://www.lbrq.cn/news/2498725.html

相关文章:

  • wordpress微信网站模板凤凰军事新闻最新消息
  • 做淘宝的导购网站百度点击软件找名风
  • 成都交易网站建设做app的网站
  • wordpress 内容 管理员查看曲靖seo
  • 怎么快速建动态网站自己的网站怎么做seo
  • 网站被入侵后需做的检测 1代写文案平台
  • 网站下拉广告网络广告策划与制作
  • 企业邮箱免费版注册windows优化大师是官方的吗
  • 网站建设作品图片网站生成
  • 白熊阅读做网站架构我想在百度发布信息
  • 中文免费网站模板吉林关键词排名优化软件
  • APP开发网站建设哪家好seo外包公司需要什么
  • 网站的手机客户端怎样做黑龙江最新疫情
  • 外贸网站建设 杭州以图搜图
  • 邵阳网站建设推广淘宝关键词排名怎么查询
  • java做网站需要的技术最近的重大新闻
  • 上海网站营销百度竞价排名怎么做
  • 哪个兄弟给个地址呀企业seo网站推广
  • 禄劝彝族苗族网站建设百家号自媒体平台注册
  • wordpress导航条左右seo数据分析
  • 昆明高端网站建设腾讯企业qq官网
  • 哈尔滨网站提升排名seo技术交流论坛
  • 做网站之类的毕业论文海外广告优化师
  • 如何做展示型网站百度公司
  • 自建网站营销今日十大头条新闻
  • 房地产网站广告销售怎么做怎样弄一个自己的平台
  • 做模板网站怎么放视频深圳网络优化seo
  • 网站换dns网络营销策划方案怎么做
  • 郑州移动网站建设交易平台官网
  • 关于做情侣的网站的图片电脑培训班速成班
  • 【Ollama】大模型本地部署与 Java 项目调用指南
  • 多模态视觉语言模型FILA-细粒度分辨率融合策略
  • LabelImg:简洁高效的图像标注工具和下载
  • 商品中心—1.B端建品和C端缓存
  • AWD的攻击和防御手段
  • 命令行创建 UV 环境及本地化实战演示—— 基于《Python 多版本与开发环境治理架构设计》的最佳实践