雜湊鍊錶hlist解惑

2021-06-21 14:05:35 字數 2097 閱讀 3888

鍊錶(list)和雜湊表(hlist)是核心常用到的兩個工具,負責組織核心中很多的資料結構,如在程序管理中用於組織程序,檔案系統中的inode節點鍊錶,dentry鍊錶,vfsmount鍊錶等等。

鍊錶使用struct list_head內嵌結構來將其寄生的結構組織成雙向迴圈鍊錶,並且表頭跟普通節點的結構相同,非常容易理解。

但雜湊表不同,其表頭跟普通節點採用不同的資料結構,並且節點的組織也不是按照普通雙向迴圈鍊錶的形式組織的。

雜湊表的表頭結構為:

struct hlist_head ;

hlist的表頭僅有乙個指向首節點的指標,而沒有指向尾節點的指標(實現完全的雙向迴圈並無必要),這樣在可能是海量的hash表中儲存的表頭就能減少一半的空間消耗。

雜湊表的節點結構為:

struct hlist_node ;

next為指向下乙個節點的指標,hlist節點的pprev不再是指向前乙個節點的指標,而是指向前乙個節點(可能是表頭)中的next(對於表頭則是first)指標,從而在表頭插入的操作可以通過一致的*(node->pprev)訪問或修改前節點的next(或first)指標。如hlist_add_before操作,在任意節點前新增節點操作是一致的,即使該節點為表頭後的第乙個節點。

static inline void hlist_add_before(struct hlist_node *n,

struct hlist_node *next)

在遍歷上,如果使用hlist_hode, list_node指標進行遍歷,兩者過程大致相似。

#define list_for_each(pos, head) \

for (pos = (head)->next; prefetch(pos->next), pos != (head); \

pos = pos->next)

#define hlist_for_each(pos, head) \

for (pos = (head)->first; pos && (); \

pos = pos->next)

如果使用其寄生結構的指標進行遍歷,則hlist與list也略有不同,hlist在遍歷時需要乙個指向hlist_node的臨時指標,該指標的引入,一是為了遍歷,而list的遍歷在list_entry的引數中實現了(紅色部分),更主要的目的在於判斷結束,因為hlist最後乙個節點的next為null,只有hlist_node指向null時才算結束,而這個null不包含在任何寄生結構內,不能通過tpos->member的方式訪問到,故臨時變數pos的引入時必須的。

#define list_for_each_entry(pos, head, member) \

for (pos = list_entry((head)->next, typeof(*pos), member); \

prefetch(pos->member.next), &pos->member != (head); \

pos = list_entry(pos->member.next, typeof(*pos), member))

#define hlist_for_each_entry(tpos, pos, head, member) \

for (pos = (head)->first; \

pos && () && \

(); \

pos = pos->next)

另外,list和hlist的遍歷都實現了safe版本,因在遍歷時,沒有任何特別的東西來阻止對鍊錶執行刪除操作(通常在使用鍊錶時使用鎖來保護併發訪問)。安全版本的遍歷函式使用臨時存放的方法是的檢索鍊錶時能不被刪除操作所影響。

#define list_for_each_safe(pos, n, head) \

for (pos = (head)->next,n = pos->next; pos != (head); \

pos = n, n = pos->next)

#define hlist_for_each_safe(pos, n, head) \

for (pos = (head)->first; pos && (); \

pos = n)

附件:在使用者空間使用的list.h標頭檔案

hlist 雜湊鍊錶

linux鍊錶設計者 因為 list.h 沒有署名,所以很可能就是 linus torvalds 認為雙頭 next prev 的雙鏈表對於 hash 表來說 過於浪費 因而另行設計了一套用於 hash 表應用的hlist資料結構 單指標表頭雙迴圈鍊錶,從上圖可以看出,hlist的表頭僅有乙個指向首...

hlist雜湊鍊錶

原文出處 http blog.chinaunix.net u 12592 showart.php?id 451619 王耀 wangyao cs.hit.edu.cn hlist雜湊鍊錶是核心中常用的乙個資料結構,由於它不同於普通的鍊錶,所以這裡對hlist雜湊鍊錶進行一下分析,希望對大家有所幫助。...

雜湊鍊錶hlist

zyd cu ydzhang.blog.chinaunix.net 鍊錶 list 和雜湊表 hlist 是核心常用到的兩個工具,負責組織核心中很多的資料結構,如在程序管理中用於組織程序,檔案系統中的inode節點鍊錶,dentry鍊錶,vfsmount鍊錶等等。鍊錶使用struct list he...