mirror of https://github.com/python/cpython
dict: Add dk_log2_index_bytes (GH-31439)
This commit is contained in:
parent
090e5c4b94
commit
1e344684d8
|
@ -68,6 +68,9 @@ struct _dictkeysobject {
|
||||||
/* Size of the hash table (dk_indices). It must be a power of 2. */
|
/* Size of the hash table (dk_indices). It must be a power of 2. */
|
||||||
uint8_t dk_log2_size;
|
uint8_t dk_log2_size;
|
||||||
|
|
||||||
|
/* Size of the hash table (dk_indices) by bytes. */
|
||||||
|
uint8_t dk_log2_index_bytes;
|
||||||
|
|
||||||
/* Kind of keys */
|
/* Kind of keys */
|
||||||
uint8_t dk_kind;
|
uint8_t dk_kind;
|
||||||
|
|
||||||
|
@ -129,7 +132,7 @@ struct _dictvalues {
|
||||||
2 : sizeof(int32_t))
|
2 : sizeof(int32_t))
|
||||||
#endif
|
#endif
|
||||||
#define DK_ENTRIES(dk) \
|
#define DK_ENTRIES(dk) \
|
||||||
((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[DK_SIZE(dk) * DK_IXSIZE(dk)]))
|
((PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))
|
||||||
|
|
||||||
extern uint64_t _pydict_global_version;
|
extern uint64_t _pydict_global_version;
|
||||||
|
|
||||||
|
|
|
@ -16,19 +16,20 @@ As of Python 3.6, this is compact and ordered. Basic idea is described here:
|
||||||
|
|
||||||
layout:
|
layout:
|
||||||
|
|
||||||
+---------------+
|
+---------------------+
|
||||||
| dk_refcnt |
|
| dk_refcnt |
|
||||||
| dk_log2_size |
|
| dk_log2_size |
|
||||||
| dk_kind |
|
| dk_log2_index_bytes |
|
||||||
| dk_usable |
|
| dk_kind |
|
||||||
| dk_nentries |
|
| dk_usable |
|
||||||
+---------------+
|
| dk_nentries |
|
||||||
| dk_indices |
|
+---------------------+
|
||||||
| |
|
| dk_indices[] |
|
||||||
+---------------+
|
| |
|
||||||
| dk_entries |
|
+---------------------+
|
||||||
| |
|
| dk_entries[] |
|
||||||
+---------------+
|
| |
|
||||||
|
+---------------------+
|
||||||
|
|
||||||
dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1)
|
dk_indices is actual hashtable. It holds index in entries, or DKIX_EMPTY(-1)
|
||||||
or DKIX_DUMMY(-2).
|
or DKIX_DUMMY(-2).
|
||||||
|
@ -444,6 +445,7 @@ estimate_log2_keysize(Py_ssize_t n)
|
||||||
static PyDictKeysObject empty_keys_struct = {
|
static PyDictKeysObject empty_keys_struct = {
|
||||||
1, /* dk_refcnt */
|
1, /* dk_refcnt */
|
||||||
0, /* dk_log2_size */
|
0, /* dk_log2_size */
|
||||||
|
0, /* dk_log2_index_bytes */
|
||||||
DICT_KEYS_SPLIT, /* dk_kind */
|
DICT_KEYS_SPLIT, /* dk_kind */
|
||||||
1, /* dk_version */
|
1, /* dk_version */
|
||||||
0, /* dk_usable (immutable) */
|
0, /* dk_usable (immutable) */
|
||||||
|
@ -562,24 +564,25 @@ static PyDictKeysObject*
|
||||||
new_keys_object(uint8_t log2_size)
|
new_keys_object(uint8_t log2_size)
|
||||||
{
|
{
|
||||||
PyDictKeysObject *dk;
|
PyDictKeysObject *dk;
|
||||||
Py_ssize_t es, usable;
|
Py_ssize_t usable;
|
||||||
|
int log2_bytes;
|
||||||
|
|
||||||
assert(log2_size >= PyDict_LOG_MINSIZE);
|
assert(log2_size >= PyDict_LOG_MINSIZE);
|
||||||
|
|
||||||
usable = USABLE_FRACTION(1<<log2_size);
|
usable = USABLE_FRACTION(1<<log2_size);
|
||||||
if (log2_size <= 7) {
|
if (log2_size < 8) {
|
||||||
es = 1;
|
log2_bytes = log2_size;
|
||||||
}
|
}
|
||||||
else if (log2_size <= 15) {
|
else if (log2_size < 16) {
|
||||||
es = 2;
|
log2_bytes = log2_size + 1;
|
||||||
}
|
}
|
||||||
#if SIZEOF_VOID_P > 4
|
#if SIZEOF_VOID_P > 4
|
||||||
else if (log2_size <= 31) {
|
else if (log2_size >= 32) {
|
||||||
es = 4;
|
log2_bytes = log2_size + 3;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
es = sizeof(Py_ssize_t);
|
log2_bytes = log2_size + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PyDict_MAXFREELIST > 0
|
#if PyDict_MAXFREELIST > 0
|
||||||
|
@ -595,7 +598,7 @@ new_keys_object(uint8_t log2_size)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
dk = PyObject_Malloc(sizeof(PyDictKeysObject)
|
dk = PyObject_Malloc(sizeof(PyDictKeysObject)
|
||||||
+ (es<<log2_size)
|
+ ((size_t)1 << log2_bytes)
|
||||||
+ sizeof(PyDictKeyEntry) * usable);
|
+ sizeof(PyDictKeyEntry) * usable);
|
||||||
if (dk == NULL) {
|
if (dk == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
@ -607,11 +610,12 @@ new_keys_object(uint8_t log2_size)
|
||||||
#endif
|
#endif
|
||||||
dk->dk_refcnt = 1;
|
dk->dk_refcnt = 1;
|
||||||
dk->dk_log2_size = log2_size;
|
dk->dk_log2_size = log2_size;
|
||||||
|
dk->dk_log2_index_bytes = log2_bytes;
|
||||||
dk->dk_kind = DICT_KEYS_UNICODE;
|
dk->dk_kind = DICT_KEYS_UNICODE;
|
||||||
dk->dk_nentries = 0;
|
dk->dk_nentries = 0;
|
||||||
dk->dk_usable = usable;
|
dk->dk_usable = usable;
|
||||||
dk->dk_version = 0;
|
dk->dk_version = 0;
|
||||||
memset(&dk->dk_indices[0], 0xff, es<<log2_size);
|
memset(&dk->dk_indices[0], 0xff, ((size_t)1 << log2_bytes));
|
||||||
memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
|
memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
|
||||||
return dk;
|
return dk;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue