contributed by < nelson0720j >
node_t 結構
目標: 找出鏈結串列的最後一個節點,並輸出指向他的指標
*left
不斷指向他的 next
所指向的節點,直到這個節點不存在為止。
同上述,不斷更新 *left
所指向的節點,每往下移長度就加一。
3. iterative Quicksort
首先, pivot
設為最左邊的點, p
為 pivot
的下一個節點。依序看 p
的 vlaue
是否比 pivot
的 value
還大, 若大於則加到 right
的鏈結串列中,反之,則加到 left
的鏈結串列中。
接下來,會分成三個鏈結串列。begin[0] 及 end[0] 紀錄 left 頭及尾端節點, begin[1] 及 end[1] 紀錄當前 pivot 節點,begin[2] 及 end[2] 紀錄 right 頭及尾端節點。
最後,迭代操作,直到分開的三個鏈結串列都只有一個節點,依序將節點加入到 result
。
Timsort
將 tail
指向 head
來達成首尾相接
接著,比較 a 和 b 所指向節點的值,若 a 小於或等於 b ,則將 a 加入 head
所指向的新佇列,反之,則將 b 加入。
find_run
找出適合的遞增 run ,再將 tp
指向當前 run 的頭節點。
merge_collapse
執行合併操作,合併最小的兩個 run 。
merge_force_collapse
會持續合併,直到 stk_size < 3 (也就是小於 3 個 run ),如果有 1 個 run ,則 build_prev_link
, 2 個則 merge_final
。
hlist_node
結構為一個雙向鏈結串列, next
指標指向下一個節點本身, pprev
為指向指標的指標,存 &next
指向前一個節點的 next
指標
目標為: 將新節點 n
加到串列前面。
先檢查 h
的成員 first
是否非空,若為空,將原先 h
的 pprev
所指向的節點( node2
)的 pprev
指向要加入的 n
的 next
。
再將 n
的 next
指向 h
的 first
原先指向的節點,即可完成 n
和原先第一個節點 h->first
的雙向鏈結。
因此 AAAA
為 h->first
。
此函式功用為找尋串列中是否有結構的值和參數 num
一樣,若有則回傳此節點的 index
。
hlist_for_each
傳入根據 mod 後的結構位址,因此 BBBB
為 &head[hash]
。
接著要取得這個結構的值來比對,這裡用一個結構 order_node
來取得值和索引,透過傳入結構,指標和成員來取得這個結構 order_node
的位址。
因此 CCCC
是 list_entry
。
hlist_add_head
他需要的參數為 hlist_head *
,因此根據 hash
,傳入目標位址。
DDDD
為 &heads[hash]
。
根據 kernel.docs
Control Groups provide a mechanism for aggregating/partitioning sets of tasks, and all their future children, into hierarchical groups with specialized behaviour.
cgroups 作用為限制,控制與隔離 Process 所使用到的系統資源。
cgroup 內可以有多個 subsystems ,各個 subsystem 分別對 cpu, memory, network 等去進行控制。
cgroup 可以以階層結構 ( Hierarchical Organization ) 的方式組織和管理,其子節點預設繼承父節點的屬性,形成一個 forest 的結構。
更多請見 cgroup v1 和 v2 介紹 , v2 kernel.docs 。
在此先觀察 cgroup v1 的 pre-order walk 程式碼,
上述程式碼會用 pre-order 的方式走過 css ( cgroup subsystem ) 的後代,並且提到會在依序走過樹的時候使用 cu_read_lock()
的函式作同步控制,確保狀態更新的一致。
另外,在 cgroup-defs.h
中的 struct cgroup_subsys_state
有提到保存 css 狀態的結構,方便管理整個樹狀的結構。
LRU可能的合法 C 程式實作
解釋:
**pprev = n->pprev
為將 pprev
指標指向 n
的 pprev
指標所指向的 next
指標,即 pprev
存 &(n->pprev)
。
解題:
先將 n
節點的前一個節點的 next
指向 n
的下一個節點(即 n->next
) 。
接著將 n
的下一個節點的 pprev
指向 n
的前一個節點的 next
,即可跳過節點 n
,達成類似刪除節點 n
的效果(實際上 n
節點仍存在)。
EEEE
為 next->pprev
。
list_entry
的第三個參數是第二個參數型態的成員,因此根據以下 LRUNode
結構,可能成員為 node
或 link
且根據 struct list_head *pos
pos指標需要存一個 list_head
型別,
因此 FFFF
為 link
。
找到結構位址後,用 list_del()
刪除結構,參數為 struct list_head *entry
,因此 GGGG
為 &cache->link
。
最後再釋放 cache
所指向的整個結構。
解釋:
函式功能為獲取指定 key 的 value,並將最近使用過的節點,也就是符合 key
值的點,透過 list_move
移動到串列頭,以此代表最近使用過,來實現 LRU 。
解題:
pos
為 hlist_node *
型別,因此 HHHH
為 node
。
void list_move(struct list_head *entry, struct list_head *head)
需傳入 list_head
型別,因此 IIII
為 &cache->link
。
這個函式用於將一個鍵值對放入LRU快取中。根據LRU快取的特性,如果快取已滿且新的鍵值對要放入,則應該淘汰最近最少使用的鍵值對。
JJJJ
為 node
,KKKK
為 &c->link
。
struct lc_element
: 代表快取中的一個元素。struct lru_cache
: 代表整個 LRU 快取。lc_create
: 用於初始化 LRU 快取。lc_get
: 通過標籤獲取元素,並可能改變活動集。lc_put
: 減少元素的引用計數,並在引用計數為零時將其移到 LRU 列表中。