U8国际 U8国际官方网站 体育APP下载08 数据结构:哈希表
栏目:U8哈希 发布时间:2025-10-10
  u8,u8国际,u8国际官方网站,u8国际网站,u8国际网址,u8国际链接,u8体育,u8体育官网,u8体育网址,u8注册,u8体育网址,u8官方网站,u8体育APP,u8体育登录,u8体育入口   本章要把上一章服务器里那些占位的代码给补上。咱们先从实现一个哈希表(Hashtables)开始。哈希表这东西,用来存放数量未知且无需排

  u8,u8国际,u8国际官方网站,u8国际网站,u8国际网址,u8国际链接,u8体育,u8体育官网,u8体育网址,u8注册,u8体育网址,u8官方网站,u8体育APP,u8体育登录,u8体育入口

U8国际 U8国际官方网站 U8体育APP下载08 数据结构:哈希表

  本章要把上一章服务器里那些占位的代码给补上。咱们先从实现一个哈希表(Hashtables)开始。哈希表这东西,用来存放数量未知且无需排序的键值对数据,那可太合适了。

  哈希表有两种:链地址法(chaining)和开放地址法(open addressing)。它们的主要区别就在于处理冲突的方式。开放地址法在遇到冲突时,会去找下一个空闲的槽位;而链地址法呢,就是用链表把冲突的键给串起来。由于找空闲槽位的方式不同,开放地址法有好多变种,相比之下,链地址法的设计就比较固定。咱们服务器里用的就是链地址法的哈希表,这玩意儿写起代码来简单,不用费太多心思做选择。

  当哈希表的大小是2的幂次方时,索引操作就只是用哈希码做个简单的按位掩码运算。

  删除操作也很简单。注意看,指针的使用让代码简洁了不少。from指针既可以是数组中的一项,也可以来自某个节点,但代码里不用区分。

  我们的哈希表大小是固定的,要是负载因子(load factor)太高,就得换个大的。在Redis里用哈希表时,还有个额外的考量。给大哈希表调整大小,得把好多节点挪到新表里去,这可能会让服务器卡顿一会儿。为了避免这种情况,我们不一下子挪动所有节点,而是用两个哈希表,慢慢地把节点在它们之间转移。下面就是最终的哈希表接口:

  哈希表实现完了,把它们加到服务器里吧。再看看HNode结构体,这玩意儿里面没数据,那咋用呢?答案就是“侵入式数据结构(intrusive data structure)”:

  我们没让数据结构包含数据,而是把哈希表节点结构嵌入到有效载荷数据里。这在C语言里可是创建通用数据结构的标准操作。这种技术不仅能让数据结构完全通用,还能减少不必要的内存管理。节点结构不是单独分配的,而是有效载荷数据的一部分,数据结构代码并不拥有有效载荷,只是负责组织数据。要是你从教科书上学数据结构,可能接触的是void *、C++模板,甚至宏,那这种方式对你来说可能还挺新鲜。

  hm_lookup函数返回一个指向HNode的指针,而HNode是Entry的一个成员,我们得用点指针运算把这个指针转成Entry指针。在C项目里,container_of宏就是干这个用的:

  ←07. 基础服务器:实现get、set、del功能09. 数据序列化→