[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]处 判断的条件明显是成立的(参见蓝色高亮部分),不理解为啥要重复判断一次,暂时想不通~
转载于:https://www.cnblogs.com/muyiblog/p/9387747.html
[cpyhon源代码]dict对象原理学习相关推荐
- Golang底层原理学习笔记(一)
LCY~~Golang底层原理学习笔记 1 源码调试 go源代码地址:GitHub - golang/go: The Go programming language 1.1 源码编译 现在的go语言大 ...
- [置顶] 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?...
盛大TeamHost上有个关于学习开源项目的wiki :http://www.teamhost.org/projects/learn-with-open-source/wiki/Wiki 一.为什么要 ...
- 为什么要阅读源代码?如何有效的阅读源代码? 选一些比较优秀的开源产品作为源代码阅读对象?
一.为什么要阅读源代码? 很多作家成名之前都阅读过大量的优秀文学作品,经过长期的阅读和写作积累,慢慢的才有可能写出一些好的.甚至是优秀的文学作品. 而程序员与此类似,很多程序员也需要阅读大量的优秀程序 ...
- MyBatis运行原理(三)接口式编程及创建代理对象原理分析
一.面向接口开发步骤 定义代理接口,将操作数据库的方法定义在代理接口中. 在SQL 映射文件中编写SQL 语句. 将SQL 映射文件注册在MyBatis 的全局配置文件中. 编写测试代码. 二.环境准 ...
- Redis主从复制原理学习
Redis主从复制原理学习总结 - 运维笔记 和Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况.为了分担读压力,Redis支持主从复制,Redis的 ...
- 热修复原理学习(1)热修复技术介绍
今天开始学习热修复的原理知识,学习方向是阿里团队编写的<深入探索Android热修复技术原理>,所以研究的热修复框架是Sophix. 之前对热修复的知识做过了解,具体是这一篇:热修复原理学 ...
- 第1课-OC对象原理基础
第1课-OC对象原理基础 [TOC] 在探索OC对象原理之前,我们首先需要了解以下知识点 1. lldb lldb是xcode自带的命令行调试工具. 我们可以通过: help:查看lldb常见命令 h ...
- Spring5底层原理 学习笔记(二)AOP篇
文章目录 AOP实现之ajc编译器 AOP实现之agent类加载 AOP实现之动态代理 jdk动态代理 演示 模拟实现动态代理 动态生成代理类需要使用到asm的api,这里就不展开了 Jdk对于反射调 ...
- Android开发如何理解Java静态代理 动态代理及动态生成代理对象原理 看这篇就够了
动态代理与静态代理 前言 代理模式 静态代理 动态代理 JDK代理 动态生成代理对象原理 生成class数据源码 动态代理类真身 总结 前言 近期在研究Hook技术,需要用到动态代理,说到动态代理就会 ...
最新文章
- SpringBoot + Mybatis + Druid + PageHelper 实现多数据源分页
- python有趣的小项目-有趣的十个Python实战项目,让你瞬间爱上Python!
- 第10篇:Flowable-BPMN操作流程部署、启动
- 浅析MySQL二进制日志
- easypoi 导入失败返回错误文件_从Excel批量导入数据说到ForkJoin的原理
- tensorrt安装_[深度学习] TensorRT安装
- 2021安新中学高考成绩查询,石家庄二中雄安校区•河北安新中学2019届冲刺高考百日誓师大会...
- modbus学习笔记——帧
- python处理词项的停用词_词项邻近 停用词 词干还原
- python 写的第一个爬虫 下载网页视频,调用迅雷下载,男神喜欢
- 力扣刷题 DAY_61 回溯
- java 奇数trun_N26-博客作业-week15
- 联想计算机不能进入系统桌面,联想笔记本电脑进不了桌面怎么办
- IT行业常用术语缩写
- 【task09】集合运算---内连结
- 分享几套免费漫画字体和卡通字体
- system information
- Teamviewer13版的安装及使用教程
- MyBatis 大于小于不等于的写法
- 文件宝局域网传输/播放功能Windows10系统经验贴(感谢文件宝用户@卡卡罗特 和@24K 純情)...
热门文章
- 15.4. syslog, klogctl - read and/or clear kernel message ring buffer; set console_loglevel
- 创维37K05HR黑屏有声音故障维修
- 2012年最后一天,终于盼到公司发报卡了
- java--HashMap与Hashtable的区别
- Spark 实时电商数据分析及可视化
- ob服务器维修视频,教你如何使用OB系统 还在看转播?你OUT了!
- MySQL高级 - 案例 - 系统性能优化 - 读写分离概述
- MySQL 高级 loop循环
- Nginx命令配置到系统环境
- Nginx服务的命令行控制