hlist_head / hlist_node 设计浅析
2015-11-18 10:44
776 查看
Linux内核提供的数据结构里,除了常见的list,还有他的另一个孪生兄弟——
就像
在这种情况下,很难想象会有这么一种需求——我们需要重新回到散列数组的位桶中,也就是说,我们不需要一个用于指向数组元素的指针。
这样,我们就省下了一个指针!或者说,省下了
22∗211∗25=218bits=215Bytes=32KB2^2 * 2^{11} * 2^5 = 2^{18} bits = 2^{15}Bytes = 32KB
但故事并没有就此结束,
想象一下,当我们插入一个节点时,注意最后一个语句
退而求其次,
至于说
这里,
hlist(由
struct hlist_head和
struct hlist_node构成)。
hlist结构如下:
struct hlist_head { struct hlist_node *first; }; struct hlist_node { struct hlist_node *next, **pprev; };
就像
hlist名字中h所预示的那样,他主要用于
hash_table。在典型的
hash_table,我们用链表处理散列冲突(colision)。此时,我们都是从数组的某一个位桶(slot)出发,沿着链表搜索,从而获取目标元素。
在这种情况下,很难想象会有这么一种需求——我们需要重新回到散列数组的位桶中,也就是说,我们不需要一个用于指向数组元素的指针。
这样,我们就省下了一个指针!或者说,省下了
n * sizeof(void *)个字节(这里的
n是散列数组的长度)。以Linux2.6.11中的
pid_hash[]、32位系统为例,共有4张表,每张表2048个slot,省下了
22∗211∗25=218bits=215Bytes=32KB2^2 * 2^{11} * 2^5 = 2^{18} bits = 2^{15}Bytes = 32KB
但故事并没有就此结束,
hlist还有个让人乍看之下颇为费解的地方——
hlist_node.pprev。这里,他不是简单地使用
struct hlist_node *指向前节点(previous node),而像是没事找事似的,是一个
struct hlist_node **指针。至于答案,还是得到源代码中去搜寻一番。为了使文章不至于充斥过多的代码,这里仅仅以添加元素为例,讲讲个中缘由。
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; if (first) first->pprev = &n->next; h->first = n; n->pprev = &h->first; }
想象一下,当我们插入一个节点时,注意最后一个语句
n->pprev = &h->first,这里,我们把
h->first的地址赋给了待插入节点的
pprev!这里就是最大的问题所在了。
hlist_node组成一个双向链表,可是他们的头节点却叫
hlist_head,这叫
hlist_node如何用一个
struct hlist_node *类型的指针去指向头节点呢?
退而求其次,
hlist_head中有一个
first域(field),用于执行整个链的第一个节点,而这个节点,逻辑上恰恰充当了head的
next域。如此一来,当我们使用
struct hlist_node **pprev指向前一个节点的
next时(在第一个节点眼里,head也是他的前驱),在整个链表中(包括头节点),我们便取得了处理的一致性,便于节点的插入删除(这也是使用双向链表的原因)。
至于说
pprev是指向前一个节点的next的指针,也可以在上面的函数中找到根据:
if (first) first->pprev = &n->next;
这里,
first不等于0,表示链表中已有元素,此时将旧的第一个元素(这里的
first)的
pprev指向新插入元素的
next。
相关文章推荐
- 【Leetcode】之Reverse Nodes in k-Group
- node.js学习资料
- 安装HomeBrew+ node + express
- 认识DOM的三大节点:元素节点,文本节点,属性节点以及nodeName,nodeType,nodeValue的区别
- Node.js Web框架之Express
- hook_load = hook_node_load
- copyFromLocal异常DataNode启动不了
- LeetCode237:Delete Node in a Linked List
- 关于机房交换机故障导致HDFS NameNode挂掉的问题(续)
- Node.js加密算法
- dom4j获取某个已知节点的值+循环名字相同的节点
- 用nodejs搭建一个简单的服务监听程序
- node.js抓取并分析网页内容有无特殊内容的js文件
- nodeJs学习
- parentNode parentElement childNodes children
- [LintCode] Remove Nth Node From End of List
- Node v0.12.5 稳定版发布
- MEAN教程2-Nodejs安装
- node.js抓取并分析网页内容有无特殊内容的js文件
- [神器推荐]node-webkit:跨平台桌面web应用的神器,非常有用(转)