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

     

转载于:https://www.cnblogs.com/muyiblog/p/9387747.html

[cpyhon源代码]dict对象原理学习相关推荐

  1. Golang底层原理学习笔记(一)

    LCY~~Golang底层原理学习笔记 1 源码调试 go源代码地址:GitHub - golang/go: The Go programming language 1.1 源码编译 现在的go语言大 ...

  2. [置顶] 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?...

    盛大TeamHost上有个关于学习开源项目的wiki :http://www.teamhost.org/projects/learn-with-open-source/wiki/Wiki 一.为什么要 ...

  3. 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?

    一.为什么要阅读源代码? 很多作家成名之前都阅读过大量的优秀文学作品,经过长期的阅读和写作积累,慢慢的才有可能写出一些好的.甚至是优秀的文学作品. 而程序员与此类似,很多程序员也需要阅读大量的优秀程序 ...

  4. MyBatis运行原理(三)接口式编程及创建代理对象原理分析

    一.面向接口开发步骤 定义代理接口,将操作数据库的方法定义在代理接口中. 在SQL 映射文件中编写SQL 语句. 将SQL 映射文件注册在MyBatis 的全局配置文件中. 编写测试代码. 二.环境准 ...

  5. Redis主从复制原理学习

    Redis主从复制原理学习总结 - 运维笔记 和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的 ...

  6. 热修复原理学习(1)热修复技术介绍

    今天开始学习热修复的原理知识,学习方向是阿里团队编写的<深入探索Android热修复技术原理>,所以研究的热修复框架是Sophix. 之前对热修复的知识做过了解,具体是这一篇:热修复原理学 ...

  7. 第1课-OC对象原理基础

    第1课-OC对象原理基础 [TOC] 在探索OC对象原理之前,我们首先需要了解以下知识点 1. lldb lldb是xcode自带的命令行调试工具. 我们可以通过: help:查看lldb常见命令 h ...

  8. Spring5底层原理 学习笔记(二)AOP篇

    文章目录 AOP实现之ajc编译器 AOP实现之agent类加载 AOP实现之动态代理 jdk动态代理 演示 模拟实现动态代理 动态生成代理类需要使用到asm的api,这里就不展开了 Jdk对于反射调 ...

  9. Android开发如何理解Java静态代理 动态代理及动态生成代理对象原理 看这篇就够了

    动态代理与静态代理 前言 代理模式 静态代理 动态代理 JDK代理 动态生成代理对象原理 生成class数据源码 动态代理类真身 总结 前言 近期在研究Hook技术,需要用到动态代理,说到动态代理就会 ...

最新文章

  1. SpringBoot + Mybatis + Druid + PageHelper 实现多数据源分页
  2. python有趣的小项目-有趣的十个Python实战项目,让你瞬间爱上Python!
  3. 第10篇:Flowable-BPMN操作流程部署、启动
  4. 浅析MySQL二进制日志
  5. easypoi 导入失败返回错误文件_从Excel批量导入数据说到ForkJoin的原理
  6. tensorrt安装_[深度学习] TensorRT安装
  7. 2021安新中学高考成绩查询,石家庄二中雄安校区•河北安新中学2019届冲刺高考百日誓师大会...
  8. modbus学习笔记——帧
  9. python处理词项的停用词_词项邻近 停用词 词干还原
  10. python 写的第一个爬虫 下载网页视频,调用迅雷下载,男神喜欢
  11. 力扣刷题 DAY_61 回溯
  12. java 奇数trun_N26-博客作业-week15
  13. 联想计算机不能进入系统桌面,联想笔记本电脑进不了桌面怎么办
  14. IT行业常用术语缩写
  15. 【task09】集合运算---内连结
  16. 分享几套免费漫画字体和卡通字体
  17. system information
  18. Teamviewer13版的安装及使用教程
  19. MyBatis 大于小于不等于的写法
  20. 文件宝局域网传输/播放功能Windows10系统经验贴(感谢文件宝用户@卡卡罗特 和@24K 純情)...

热门文章

  1. 15.4. syslog, klogctl - read and/or clear kernel message ring buffer; set console_loglevel
  2. 创维37K05HR黑屏有声音故障维修
  3. 2012年最后一天,终于盼到公司发报卡了
  4. java--HashMap与Hashtable的区别
  5. Spark 实时电商数据分析及可视化
  6. ob服务器维修视频,教你如何使用OB系统 还在看转播?你OUT了!
  7. MySQL高级 - 案例 - 系统性能优化 - 读写分离概述
  8. MySQL 高级 loop循环
  9. Nginx命令配置到系统环境
  10. Nginx服务的命令行控制