Python中Dict的查找

Dict的类型的查找使用的是lookdict函数

static PyDictKeyEntry *
lookdict(PyDictObject *mp, PyObject *key,Py_hash_t hash, PyObject ***value_addr)

函数的参数中,*value_addr是指向匹配slot中值的指针。 这个函数在正确的情况下一定会返回一个指向slot的指针,出错则会返回NULL。 如果成功找到了匹配的slot,则返回对应的slot; 如果没有匹配的slot,则返回查找链上第一个未被使用的slot。 该slot可以是unused状态,也可以是dummy状态。

    mask = DK_MASK(mp->ma_keys);ep0 = &mp->ma_keys->dk_entries[0];i = (size_t)hash & mask;

计算了slot的初始位置,把hash值映射到slot table的下标范围内。 初始位置=hash&mask,mask=dk_size-1

    if (ep->me_key == NULL || ep->me_key == key) {*value_addr = &ep->me_value;return ep;}

如果找到了匹配的key或unused slot,返回该结果即可。

    if (ep->me_key == dummy)freeslot = ep;else {if (ep->me_hash == hash) {startkey = ep->me_key;Py_INCREF(startkey);cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);Py_DECREF(startkey);if (cmp < 0)return NULL;if (ep0 == mp->ma_keys->dk_entries && ep->me_key == startkey) {if (cmp > 0) {*value_addr = &ep->me_value;return ep;}}else {/* The dict was mutated, restart */goto top;}}freeslot = NULL;}

进一步的比较。 若该slot状态为dummy,则用freeslot记录该slot并继续搜索; 如果该slot的hash值与待搜索key的hash相同,那么对两个key进行比较。 这里的PyObject_RichCompareBool是一个比较函数,其第三个参数为比较的操作。 如果操作结果为true,返回1;为false,返回0;比较出错,返回-1。 比较出错的情况下会返回NULL,比较成功(在这里为相等)返回该slot,比较不成功则继续进行搜索。 这一部分进行了第一次的搜索;在dict容量不太满时,一般在这里就可以找到合适的结果。

        i = (i << 2) + i + perturb + 1;ep = &ep0[i & mask];if (ep->me_key == NULL) {if (freeslot == NULL) {*value_addr = &ep->me_value;return ep;} else {*value_addr = &freeslot->me_value;return freeslot;}}

找到了unused slot的情况。 如果freeslot是NULL,那么返回该slot即可;若freeslot不是NULL,那么返回freeslot。

        if (ep->me_key == key) {*value_addr = &ep->me_value;return ep;}

找到了匹配的key。此情况返回对应slot即可。

        if (ep->me_hash == hash && ep->me_key != dummy) {startkey = ep->me_key;Py_INCREF(startkey);cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);Py_DECREF(startkey);if (cmp < 0) {*value_addr = NULL;return NULL;}if (ep0 == mp->ma_keys->dk_entries && ep->me_key == startkey) {if (cmp > 0) {*value_addr = &ep->me_value;return ep;}}else {/* The dict was mutated, restart */goto top;}}

该slot hash值与给定hash值相同时进一步比较的情况。

        else if (ep->me_key == dummy && freeslot == NULL)freeslot = ep;

在dummy情况下设置freeslot。

 

在搜索过程中,原则是找到和key相等的对象即可。 那么什么是和key相等呢? 一种情况是它们的引用相等,自然的值也相等。 这类比较只需要直接比较对应指针是否相等呢该即可。 而另一种情况是引用不相等,但值还相等。 如果没有对这种情况的处理,那么对于非共享的对象来说搜索几乎不会得到正确的结果。 搜索中的进一步比较就是对这种情况的处理。 进一步比较发生的前提是hash值相等,因为值相等必然有hash相等, 但hash相等值却可能不等,因此不能直接比较hash值,还需要更进一步的比较值才可以。

转载于:https://www.cnblogs.com/ruizhang3/p/6888006.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文字特效代码大全

代码收集来源于网络博友,感谢博友提供,本人只收集,整理,说明. 1.删除线:<FONT style"TEXT-DECORATION: line-through">写上你想写的字</FONT> 效果如下 写上你想写的字 2.文字顶部加横线:<font style"text-decoration:overline">写上你想…

oracle 会话实例,返璞归真:Oracle实例级别和会话级别的参数设置辨析

杨廷琨(yangtingkun)云和恩墨 CTO高级咨询顾问&#xff0c;Oracle ACE 总监&#xff0c;ITPUB Oracle 数据库管理版版主参数文件是Oracle数据库文件中级别最低&#xff0c;也是最基本的文件&#xff0c;但是也是数据库实例启动第一个涉及的文件。如果参数文件缺失或者某些参数设…

ExtJs CheckboxSelectionModel 全选操作后 清空表格头的checkBox

关键代码&#xff1a; var hd Ext.getCmp("interviewSubscriptionGrid").getEl().select(div.x-grid3-hd-checker).first(); if (hd.hasClass(x-grid3-hd-checker-on)) { hd.removeClass(x-grid3-hd-checker-on); } 转自&#xff1a;ExtJs Checkbox…

在多节点集群中运行Cassandra

这篇文章收集了我在多节点中设置Apache Cassandra集群的步骤。 在设置集群时&#xff0c;我已经参考了Cassandra Wiki和Datastax文档。 详细介绍了以下过程&#xff0c;分享了我建立群集的经验。 设置第一个节点 添加其他节点 监视集群– nodetool &#xff0c; jConsole &am…

Oracle 添加 scott 示例用户

学习SQL有一段时间了&#xff0c;但是也忘记的差不多了&#xff0c;今天有赶紧复习复习&#xff0c;然后发现一个问题&#xff0c;为啥之前看的视频教程&#xff0c;马士兵用的Oracle有scott用户和那些表格&#xff0c;而我的没有&#xff1f;难道是Oracle取消了&#xff1f;然…

win8oracle10g安装报错,Win8电脑安装Oracle 10g提示程序异常终止的解决方法

有win8系统用户反映说在安装Oracle 10g的时候&#xff0c;选择高级安装之后&#xff0c;就弹出一个窗口&#xff0c;提示程序异常终止&#xff0c;发生内部错误&#xff0c;导致Oracle 10g安装失败&#xff0c;该怎么解决这样的问题呢&#xff1f;下面随小编一起来看看Win8电脑…

MFC的消息循环

MFC的消息循环 消息分为队列消息(进入线程的消息队列)和非队列消息(不进入线程的消息队列)。对于队列消息&#xff0c;最常见的是鼠标和键盘触发的消息&#xff0c;例如WM_MOUSERMOVE,WM_CHAR等消息&#xff1b;还有例如&#xff1a;WM_PAINT、WM_TIMER和WM_QUIT。当鼠标、键…

<avatar: frontiers of pandora>技术overview

https://www.eurogamer.net/digitalfoundry-2023-avatar-frontiers-of-pandora-and-snowdrop-the-big-developer-tech-interview https://www.youtube.com/watch?vLRI_qgVSwMY&t394s 主要来自euro gamer上digital foundry对于avatar的开发团队Massive工作室的采访&#xf…

使用Hibernate 4,JPA和Maven的架构创建脚本

这种情况很简单–您想要在构建应用程序时生成数据库模式创建脚本&#xff08;然后在目标数据库上执行脚本&#xff09;&#xff0c;这对于Hibernate 3来说相对容易&#xff0c;因为有 hibernate3-maven-plugin &#xff0c;但是与Hibernate 4不兼容。当然&#xff0c;对于每个新…

iOS 启动连续闪退保护方案

版权声明&#xff1a;本文由刘笑江原创文章&#xff0c;转载请注明出处: 文章原文链接&#xff1a;https://www.qcloud.com/community/article/79 来源&#xff1a;腾云阁 https://www.qcloud.com/community 一.引言 “如果某个实体表现出以下任何一种特性&#xff0c;它就具备…

实战Java内存泄漏问题分析 -- hazelcast2.0.3使用时内存泄漏 -- 2

hazelcast 提供了3中方法调用startCleanup:第一种是在ConcuurentMapManager的构造函数中&#xff0c;通过调用node的executorManager中的ScheduledExecutorService来创建每秒运行一次cleanup操作的线程&#xff08;代码例如以下&#xff09;。因为这是ConcuurentMapManager构造…

oracle 11203 ora32701,11G RAC ORA-32701 参考学习

节点1&#xff1a;Wed Feb 13 16:08:06 2019Errors in file /u01/app/oracle/diag/rdbms/testdb/testdb1/trace/testdb1_dia0_9267.trc (incident1248083):ORA-32701: Possible hangs up to hang ID4 detectedIncident details in: /u01/app/oracle/diag/rdbms/testdb/testdb1/…

使用@OrderBy对Spring Data MongoDB集合进行排序

这是关于调整和增强Spring Data MongoDB功能的第三篇文章。 这次&#xff0c;我发现我错过了一个JPA功能– OrderBy批注。 OrderBy指定在检索关联值时集合值关联的元素的顺序。 在本文中&#xff0c;我将展示如何使用Spring Data MongoDB使用OrderBy批注实现排序 。 用例 对…

@SuppressLint(NewApi)和@TargetApi()的区别

转自&#xff1a;http://blog.csdn.NET/wbshuang09/article/details/44920549在Android代码中&#xff0c;我们有时会使用比我们在AndroidManifest中设置的android:minSdkVersion版本更高的方法&#xff0c;此时编译器会提示警告&#xff0c;解决方法是在方法上加上SuppressLin…

零基础自学编程前需要知道的知识

你是否适合编程?学习编程后能做什么?如何选择编程语言?有哪些免费的线上学习网站推荐?今天这篇好文将那些自学编程前需要了解和思考的问题都记录下来&#xff0c;希望能给那些刚刚开始或正准备自学编程的朋友们带去一些启发。 你是否适合自学编程 自学编程会是一个漫长而艰…

oracle系统库名,Oracle 札记之 一:数据库名,数据库实例名,数据库域名,操作系统环境变量...

数据库名是用于区分数据库的一个内部标识&#xff0c;是以二进制方式存储在数据库控制文件中的参数。数据库创建之后不能再修改这个参数。数据库创建后&#xff0c;它被写入数据库参数文件pfile或Spfile中。格式如下&#xff1a;...db_name"orcl"db_domaindbcenter.t…

用于基于SWT的应用程序的RichText编辑器组件

本文将完成使用SWT实现我们自己的RichText编辑器组件的任务。 在为我的一位客户开发基于桌面的应用程序时&#xff0c;我遇到了这样一个可视化组件的需求&#xff0c;并希望添加一项功能&#xff0c;以允许用户使用粗体&#xff0c;斜体&#xff0c;删除线等功能来写富文本注释…

Eclipse设置黑色主题

1点击help--->install new software 2输入 http://eclipse-color-theme.github.com/update 3下载安装eclipse color theme插件如下图 4完成后点击windows--->preferences------>Appearance下多了一个Color Theme 5,点击选择喜欢的主题即可&#xff0c;也可以自己下载主…

wcf rest系列文章

http://www.cnblogs.com/artech/archive/2012/02/15/wcf-rest.html 需要注意的是&#xff0c;发布的服务&#xff0c;可以在web behavior中指定显示help页面。 http://localhost/ApplicationName/ServiceName.svc/help 需要注意的是&#xff0c;访问.svc的页面一定不要多加/;否…

登录:应用程序错误通知

几个月前&#xff0c;当我进行大型应用程序重构时&#xff0c;发现用于记录日志的基于log4j的代码确实令人讨厌&#xff0c;重复了数百次&#xff1a; if (LOG.isDebugEnabled()) {LOG.debug("Logging some stuff " stuff); }我想摆脱isXXXEnabled&#xff0c;这就…