1. 程式人生 > >[cpyhon源代碼]dict對象原理學習

[cpyhon源代碼]dict對象原理學習

pyo 之前 cto 不理解 pan rsa return cte 2.7

Cpython 2.7 分支中,dict 對象的源代碼 lookdict 搜索算法

 1 static PyDictEntry *
 2 lookdict(PyDictObject *mp, PyObject *key, register long hash)
 3 {
 4     register size_t i;
 5     register size_t perturb;
 6     register PyDictEntry *freeslot;
 7     register size_t mask = (size_t)mp->ma_mask;
 8     PyDictEntry *ep0 = mp->ma_table;
9 register PyDictEntry *ep; 10 register int cmp; 11 PyObject *startkey; 12 13 i = (size_t)hash & mask; 14 ep = &ep0[i]; 15 if (ep->me_key == NULL || ep->me_key == key) //【1】 16 return ep; 17 18 if (ep->me_key == dummy) 19 freeslot = ep; 20 else
{ 21 //進到這裏說明 ep->me-key !=NULL && ep->me_key!=key && ep->me_key==Active 22 if (ep->me_hash == hash) { 23 startkey = ep->me_key; 24 Py_INCREF(startkey); 25 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); //[2]這裏為啥要再比較一次? 26
Py_DECREF(startkey); 27 if (cmp < 0) 28 return NULL; 29 if (ep0 == mp->ma_table && ep->me_key == startkey) {//[3]這裏明顯是相等的,為啥要再判斷一次? 30 if (cmp > 0) 31 return ep; 32 } 33 else { 34 /* The compare did major nasty stuff to the 35 * dict: start over. 36 * XXX A clever adversary could prevent this 37 * XXX from terminating. 38 */ 39 return lookdict(mp, key, hash); 40 } 41 } 42 freeslot = NULL; 43 }

  

兩個問題無法理解:

  1.1 dict 對象搜索算法中,進入【2】處已經說明了 ep->me_key!=key 這個條件成立,但是 【2】那裏為啥要再次比較一次 me_key 和 key 呢?

百思不得其解!!!

原因: 【1】處為兩個指針做 == 比較,說明指針的內容相同,即指向的是同一對象

進入到流程【2】則說明兩個對象指向不同的內存,但是在滿足兩個條件後也認為他們“相等”,從而返回對應的項目,條件如下:

一是 兩個對象哈希值相等

二是 兩個對象的值相等(比較算法由對象提供,通常是 __eq__方法)

舉例:dict[10000]=10,此時需要搜索 d[10000]對象的 entry 對象,搜索時 指向 10000 的Pyobject* 明顯和之前 存入 dict[10000] 值時對應的

Pyobject 指針不一致,此時 p(p->int(10000) me_key) != q(q->int(10000) key),因此不會進入流程 【1】

但是 p,q同時滿足規定的兩個條件,即hash值和 ob_val 都一致,因此返回 p 處的 (key,value)entry

1.2 [3]處 判斷的條件明顯是成立的(參見藍色高亮部分),不理解為啥要重復判斷一次,暫時想不通~

[cpyhon源代碼]dict對象原理學習