首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

Python源码学习之初始化(3)-PyDictObject的初始化

2013-09-28 
Python源码学习之初始化(三)-PyDictObject的初始化先来看它的定义typedef struct _dictobject PyDictObjec

Python源码学习之初始化(三)-PyDictObject的初始化

先来看它的定义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, Py_hash_t hash);    PyDictEntry ma_smalltable[PyDict_MINSIZE];};在PyObject *PyDict_New(void)中,调用了宏定义EMPTY_TO_MINSIZE#define INIT_NONZERO_DICT_SLOTS(mp) do {                                \    (mp)->ma_table = (mp)->ma_smalltable;                               \    (mp)->ma_mask = PyDict_MINSIZE - 1;                                 \    } while(0)#define EMPTY_TO_MINSIZE(mp) do {                                       \    memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable));        \    (mp)->ma_used = (mp)->ma_fill = 0;                                  \    INIT_NONZERO_DICT_SLOTS(mp);                                        \    } while(0)可以看出ma_table开始是指向ma_smalltable的,这和代码的注释一致mp->ma_lookup = lookdict_unicode; 给函数指针赋值,dict的搜索函数随着int PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)的不断调用该函数会在最后判断    if (!(mp->ma_used > n_used && mp->ma_fill*3 >= (mp->ma_mask+1)*2))        return 0;    return dictresize(mp, (mp->ma_used > 50000 ? 2 : 4) * mp->ma_used);可见在ma_fill = 6 && ma_mask=7 的时候,走到了dictresize会重新申请新的内存, ma_table就不再指向ma_smalltable, 而是新的内存,然后把原来老的内容拷贝到新的内存里面.by calling insertdict_clean之后 ma_fill = ma_used = 6, ma_mask = 31    /* Get space for a new table. */    oldtable = mp->ma_table;    assert(oldtable != NULL);    is_oldtable_malloced = oldtable != mp->ma_smalltable;    if (is_oldtable_malloced)        PyMem_DEL(oldtable);最后看老的内存是否应该释放如果老的是ma_smalltable, 就不管了

热点排行