核心資料結構:hlist_head

來源:互聯網
上載者:User

 

原文地址:http://blog.csdn.net/ronliu/article/details/6425368

核心中,使用list_head作為鏈表,該資料結構本身即使head又是node。如果將它作為hash list的前端節點,那麼每個前端節點會佔用8個位元組。因此核心中對其最佳化,使用hlist_head作為hash表的前端節點。核心中定義其資料結構為:

struct hlist_head {
struct hlist_node *first;
};

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

注意到,這裡的pprev是一個二級指標。為什麼這樣設計呢,有什麼優點?

在中,pprev是指向前一節點next指標的指標。first是hlist_head的欄位,指向第一個節點。

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;
}

 

static inline void __hlist_del(struct hlist_node *n)

{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;

/*這裡修改的其實是它的前一節點的next值。無論該節點是不是前端節點*/    
<<<<1
*pprev = next;   

/*這裡修改它的後節點的pprev值,比較好理解。*/

if (next)
  next->pprev = pprev;
}

 

如果hlist_node中使用的是單級指標,那麼在1處就需要判斷節點是否為前端節點。可以用n->prev是否被賦值,即是否為NULL來區分頭結點和普通節點。在add和delete時都很容易保證前端節點的prev為NULL。

比如這樣判斷:

struct my_hlist_node *next = n->next ;

struct my_hlist_node *prev = n->prev ;

if(n->prev)

    n->prev->next = next ;

else

    n->prev = NULL ;

if(next)

    next->prev = prev ;

為什麼不這樣做?有兩個原因:

1. 代碼不夠簡潔優雅。使用hlist_node,頭結點和普通節點是一致的。

2. pprev有一個作用,在hlist_unhashed()中有體現。

static inline int hlist_unhashed(const struct hlist_node *h)

{
return !h->pprev;   /*是否為NULL,被用來判斷節點是否加入到hash list中。*/

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.