一、内核中的哈希表

哈希表在内核位置/include/linux/types.h

struct hlist_head {struct hlist_node *first;
};struct hlist_node {struct hlist_node *next, **pprev;
};

今天,我们带着问题去理解Linux内核中的哈希表结构。

1.那么为什么哈希表中头节点hlist_head与其他节点hlist_node不同,而没有采用相同的结构体呢?

因为哈希表中一般采用单散列的形式,并不需要双链表的双向循环功能,所以Linux内核为了减少开销,并没有用hlist_node来指定哈希表头结点,而是采用了hlist_head结构,以减少存储空间的占用。头结点的数量与数据的总量在同一个数量级。

2.为什么在hlist_node中prev采用了二级指针,而没有采用单链表,或双向链表的形式呢?

(1)若使用单链表结构,在插入节点的时候可以采用在哈希表的头结点之后插入节点,此时时间复杂度为O(1)。但在删除节点的时候必须要遍历链表来寻找待删除节点的前一个节点,此时效率较低。
(2)若prev采用一级指针,则链表的形式如下:

为了间接改变表头中hlist_node类型first指针的值,使用了二级指针,因此在node节点中pprev中保存的为前一个结点中第一个元素的地址,头结点中即为first指针,其余节点则为next。

删除一个节点

删除第一个节点的操作方式如下:

*(node1->pprev) = node1->next;
node1->next->pprev = node1->pprev;

删除其余节点的操作方式如下(以node2节点为例):

*(node2->pprev) = node2->next;
node2->next->pprev = node2->pprev;

插入第一个节点:

node1->pprev = &(my_list->first);
node1->next = my_list->first;//初始化时,first指针指向NULL
mylist->first = node1;

插入其余节点(以node2为例):

头插法

node2->pprev = &(my_list->first);
node2->next = my_list->first; // 或node1,为了与插入第一个节点的操作保持一致
my_list->first = node2;

尾插法

node2->pprev = &(node1->next);
node2->next = node1->next;
node1->next = node2;

这样一来所有节点的删除和插入操作方式都是完全一样的。

哈希表中的宏定义

//初始化头结点
#define HLIST_HEAD_INIT { .first = NULL }
//声明并初始化头结点
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
//初始化头结点
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
//初始化其他节点
#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL)

其中{ .first = NULL }这个代码段的作用是,将hlist_head结构体中的first元素初始化为0。是根据结构体中的变量名来区分元素的。

内核中的哈希表结构

Linux内核数据结构之哈希表相关推荐

  1. linux内核中的 哈希表_Linux内核中的设备模型及SCSI示例解析

    关于硬件架构 想要了解Linux操作系统的内核设备和驱动模型,最好先了解一下现在计算机硬件的架构.对计算机硬件有一定了解之后,对理解Linux内核中的设备和驱动模型非常有帮助.如图1是常规计算机的硬件 ...

  2. Python数据结构:哈希表

    哈希 散列(哈希)是电脑科学中一种对资料的处理方法,通过某种特定的函数/算法(称为散列函数/算法)将要检索的项与用来检索的索引(称为散列,或者散列值)关联起来,生成一种便于搜索的数据结构(称为散列表) ...

  3. PHP内核中的哈希表结构

    https://github.com/HonestQiao/tipi/commit/17ca680289e490763a6a402f79afa2a13802bb36 下载:https://github ...

  4. go移植linux内核书名叫啥,Go语言移植Linux内核数据结构hlist

    hlist(哈希链表)可以通过相应的Hash算法,迅速找到相关的链表Head及节点. 在有些应用场景,比Go标准库提供的list(一种双向链表)更合适. 依照list.h中的源码,我实现了一个Go语言 ...

  5. 图书馆管理系统(C、数据结构、哈希表、文件IO)

    目录 技术路线 实现效果展示 ​程序主体 1.头文件部分 2.自定义函数定义部分 3.main函数部分 注意 技术路线 数据结构.哈希表.文件IO 通过C语言进行程序设计,有用到数据结构中的哈希表,通 ...

  6. 用c语言实现基本数据结构(哈希表)

    用c语言实现基本数据结构(哈希表) 写这个哈希表总是段错误,找了半天的bug...原来是各种小错误不断,写得很蛋疼. 我是是用数组实现的,数组的最大值定义成的宏.一共只有四个函数,分别为初始化哈希表, ...

  7. C++八股文分享---数据结构其二---哈希表

    C++八股文分享-数据结构其二-哈希表 前言 什么是哈希表? 搜索二叉树对值的查找是通过从根节点开始,逐个节点与目标值做比较,向下查找,直至找到目标值或是到达根节点未查找到,时间复杂度为O(logn) ...

  8. 【数据结构】哈希表的概念及应用

    [数据结构]哈希表的概念及应用 前言 1.写出哈希表的基本概念 2.列出常用的哈希函数构造方法,并阐述各自的特点. 直接定址法 除留余数法 数字分析法 其他构造整数关键字的哈希函数的方法: 平方取中法 ...

  9. 「Redis数据结构」哈希表(Dict)

    「Redis数据结构」哈希表(Dict) 文章目录 「Redis数据结构」哈希表(Dict) @[toc] 一.概述 二.结构 三.哈希冲突 四.链式哈希 五.rehash 六. 渐进式 rehash ...

  10. linux内核数据结构实现--链表、队列和哈希

    C是面向过程的语言,但是linux内核却用C实现了一套面向对象的设计模式,linux内核中处处体现着面向对象的思想. 1. 内核链表和list_entry 1.1 普通链表实现 我们在语法书上学到的链 ...

最新文章

  1. python【力扣LeetCode算法题库】55-跳跃游戏
  2. CTF的一道安卓逆向
  3. java的concurrent包
  4. 界面发布2019中国最富1000人榜:凛冬望春,马云问鼎中国首富
  5. 旅行场景下的推荐算法探索
  6. TypeScript之基本数据类型
  7. java类的参考文献,太完整了!
  8. CIM即时通讯源码初步解析(一款个人推荐的带集群的开源项目)
  9. python画图的函数_python画图函数
  10. 用python做youtube自动化下载器 代码
  11. java实现中国象棋3:走棋规则的实现
  12. Vim快捷键汇总 - Jeffery Lee的专栏 - CSDNBlog
  13. 这就是你日日夜夜想要的docker!!!---------TLS加密远程连接Docker
  14. Bash Specially-crafted Environment Variables Code Injection Vulnerability Analysis
  15. 暴走欧洲之文明的迭代
  16. gentoo问题汇总
  17. eclipse的web项目中index.jsp文件出现The superclass was not found on the java build path
  18. 高级JAVA开发必备技能:java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量)(JAVA 小虚竹)
  19. 电脑怎么直接给服务器传文件夹,教你电脑怎么传文件夹给qq好友
  20. Android存放图片尺寸规范

热门文章

  1. PRINCE2 项目管理方法论框架介绍
  2. 【笔记篇】01初识供应链——之《实战供应链》
  3. Java聊天室yadiChat step1 登陆注册
  4. 《网络运维 - 基础知识》
  5. PMP 11章 项目风险管理
  6. HDFS 纠删码 EC
  7. YYText学习之根据range设置text的颜色和边框
  8. Alpha-Beta剪枝算法原理
  9. 尔雅 2017大学计算机基础答案,2018超星尔雅大学计算机基础答案.docx
  10. 服务器怎么开启lldp协议,修改服务器lldp的mac地址