[笔记]PyDictObject头文件阅读

dictobject.h

PyDictObject是一种字典类型,从可哈希的对象映射到另一个对象。

然后提到了在Objects目录下,有dictnotes.txt文件,关于字典的使用设计和优化。

字典类实际上是维护了一张哈希表,而表项,entry or slot,有3种状态。

1. Unused.  me_key == me_value == NULL

未使用状态,key和value都为空。

这是表项的初始状态,仅当初始时key才会为空。

2. Active.  me_key != NULL and me_key != dummy and me_value != NULL

正在使用状态,key不为空且不为dummy,value不为空。

3. Dummy.  me_key == dummy and me_value == NULL

曾使用状态,但该表项已经被删除了。key为dummy,value为空。

设置Dummy状态是因为Python面对hash冲突时所采取的是开放地址法,会再次寻找位置。

所以会产生探索链这样的关联结构,比如A、B、C三者的哈希值一样,那么会处在一条探索链上。

当B被删除后,为了保证能够搜索到C,特地设置Dummy值,表示后面还可能存在有效表项。

#define PyDict_MINSIZE 8

PyDict_MINSIZE是一个字典的最小大小,这个“小字典”是直接作为表项的成员的,ma_smalltable。

表项的结构如下:

typedef struct {
    /* Cached hash code of me_key.  Note that hash codes are C longs.
     * We have to use Py_ssize_t instead because dict_popitem() abuses
     * me_hash to hold a search finger.
     */
    Py_ssize_t me_hash;
    PyObject *me_key;
    PyObject *me_value;
} PyDictEntry;

由注释可以知道me_hash的一个作用是避免重复计算,另一个作用是可以用来指向探索链的下一个。

字典的结构如下:

typedef struct _dictobject PyDictObject;
struct _dictobject {
    PyObject_HEAD
    Py_ssize_t ma_fill;  /* # Active + # Dummy */
    Py_ssize_t ma_used;  /* # Active */

    /* The table contains ma_mask + 1 slots, and that's a power of 2.
     * We store the mask instead of the size because the mask is more
     * frequently needed.
     */
    Py_ssize_t ma_mask;

    /* ma_table points to ma_smalltable for small tables, else to
     * additional malloc'ed memory.  ma_table is never NULL!  This rule
     * saves repeated runtime null-tests in the workhorse getitem and
     * setitem calls.
     */
    PyDictEntry *ma_table;
    PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash);
    PyDictEntry ma_smalltable[PyDict_MINSIZE];
};

由注释可知ma_fill和ma_used的含义。

ma_mask经常用来与key的哈希值进行与运算,使其落在表的范围内。

ma_table指向ma_smalltable或者另外分配的内存。

为了保证在表中搜索位置的过程会终止,表中至少有一项Unused。

另外为了避免低效搜索,当有三分之二的表项被使用了,会重新调整表的大小。


JasonLee     2011.08.14     23:35     明天又周一了,今天大连散步

时间: 2024-11-05 12:13:34

[笔记]PyDictObject头文件阅读的相关文章

C++中头文件和源文件详细介绍

C++中的头文件和源文件详解 一.C++编译模式 通常,在一个C++程序中,只包含两类文件--.cpp文件和.h文件.其中,.cpp文件被称作C++源文件,里面放的都是C++的源代码:而.h文件则被称作C++头文件,里面放的也是C++的源代码. C+ +语言支持"分别编译"(separate compilation).也就是说,一个程序所有的内容,可以分成不同的部分分别放在不同的.cpp文件里..cpp文件里的东西都是相对独立的,在编 译(compile)时不需要与其他文件互通,只需要

程序设计方式 之 嵌套头文件包含方式

       一直以来写程序有个习惯,喜欢把常用的STL类,或者其他常用的类,变量,宏等定义到一个文件内,然后在使用其中一个类的地方包含这个文件.一直再使用,也一直存在困惑,这种设计方式的能否放心大胆的使用,对它始终心存畏惧,所有这些促使我完成这篇文章,并且经过种种测试,有足够的信心继续使用这种设计方式.        操作如下 定义base.h文件,包含基本的STL类,并且通过typedef建立不同的映射关系,以便减少不同的文件出现过多vector<string>之类的声明方式.当需要使用v

大型项目开发: 头文件顺序

经验告诉我们,某些编码实践虽然在C++中完全合法,但是绝对不能应用于大型项目环境中. 大型项目环境下必须有适当的约束,否则很容易变得难以控制并很难维护(摘自<<大规模C++程序设计>>).下面以Chromium中运用的两个Coding Style中定义的头文件顺序为例. 头文件顺序的差异 WebKit/Blink遵循业界标准的定义,其实也是Lakos在<<大规模C++程序设计>>中建议的顺序 : 编译单元对应的头文件 (Related header file

c-STM8S105C4T6单片机的头文件

问题描述 STM8S105C4T6单片机的头文件 2C 请问一下谁有STM8S105C4T6单片机的头文件?给我一份.我现在用的是IOSTM8S003K3.h.因为一直找不到STM8S105C4T6.h所以就用了IOSTM8S003K3.h但是却报错找不到 REN TEN RIENTXE RXNE这些.是不是这几个端口在别的头文件里,还是我的头文件用错了. 解决方案 实在找不到就按照STM8S 串口初始化设置里面的自己定义一下

头文件 函数主体-急!!研究源代码,找不到函数的主体!

问题描述 急!!研究源代码,找不到函数的主体! 为什么用sourcelight察看源代码会发现有些函数只在头文件中定义了,但却找不到函数的主体? /* database handling */ extern int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options); extern const char *cl_retdbdir(void); 就是这两个函数

头文件-请问ubuntu内有自带的单向hash函数吗?

问题描述 请问ubuntu内有自带的单向hash函数吗? 就是把一个大文件快速hash成一个小文件,有这样的函数吗?头文件在那个目录里呢? 解决方案 这和ubuntu没有什么关系. google下md5 sha1 sha256 rc4等等各种散列的函数有很多. 解决方案二: ubuntu自带有md5sum等命令 解决方案三: 参考:http://blog.csdn.net/xhhjin/article/details/8450686

ndk-Android NDk 怎么编译时动态链接第三方so库,有头文件

问题描述 Android NDk 怎么编译时动态链接第三方so库,有头文件 最近在做一个项目,大神把底层的算法封装成so(普通的c++函数),并给出头文件,我需要先 进行封装,然后给java调用.在我写的C++(符合JNI规范)里面调用so库函数, 下面贴图求解答: 1.项目的目录结构 其中 libvvw.so就是第三方库: Test_vvw.h就是第三方库的头文件 2.java 的native方法定义 3.native的实现方法体 FrameDecode.cpp文件 4.Android.mk文

VC++6.0如何添加头文件(graphics.h)??

问题描述 VC++6.0如何添加头文件(graphics.h)?? 'graphics.h': No such file or directory Error executing cl.exe. 编译中出现这个问题(本人初学者),网上说要添加头文件,按照网上的教程结果错误更多了,头文件添加不成功,请求大神支援,怎么破??? (详细一点可以么?最好附上截图,万分感谢!) 解决方案 初学者的话,建议你换Borland C++或者Turbo C++ 这是是属于DOS时代Borland搞出来的一个绘图库

eclipse中头文件无法识别??

问题描述 eclipse中头文件无法识别?? 解决方案 c++中头文件C++中头文件