zoukankan      html  css  js  c++  java
  • [cpyhon源代码]dict对象原理学习

    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]处 判断的条件明显是成立的(参见蓝色高亮部分),不理解为啥要重复判断一次,暂时想不通~

         

  • 相关阅读:
    jQuery学习笔记
    MAMP的使用
    svn使用
    Docker 下安装 MySQL时,docker-compose.yml 的写法
    MySQL 8报错:The user specified as a definer ('mysql.infoschema'@'localhost') does not exist
    Zookeeper 总结及安装
    Docker 在 Linux 下的安装与配置
    Linux更换国内软件源
    gitlab-runner一直处于挂起/pedding状态
    GitLab出现forbidden的解决方法
  • 原文地址:https://www.cnblogs.com/muyiblog/p/9387747.html
Copyright © 2011-2022 走看看