Kaydet (Commit) 4b74fba6 authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Issue 21101: Internal API for dict getitem and setitem where the hash value is known.

üst 1b5eebcf
......@@ -50,6 +50,8 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type;
PyAPI_FUNC(PyObject *) PyDict_New(void);
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
Py_hash_t hash);
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
struct _Py_Identifier *key);
......@@ -58,6 +60,8 @@ PyAPI_FUNC(PyObject *) PyDict_SetDefault(
PyObject *mp, PyObject *key, PyObject *defaultobj);
#endif
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
PyObject *item, Py_hash_t hash);
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
PyAPI_FUNC(int) PyDict_Next(
......
......@@ -1101,6 +1101,44 @@ PyDict_GetItem(PyObject *op, PyObject *key)
return *value_addr;
}
PyObject *
_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
{
PyDictObject *mp = (PyDictObject *)op;
PyDictKeyEntry *ep;
PyThreadState *tstate;
PyObject **value_addr;
if (!PyDict_Check(op))
return NULL;
/* We can arrive here with a NULL tstate during initialization: try
running "python -Wi" for an example related to string interning.
Let's just hope that no exception occurs then... This must be
_PyThreadState_Current and not PyThreadState_GET() because in debug
mode, the latter complains if tstate is NULL. */
tstate = (PyThreadState*)_Py_atomic_load_relaxed(
&_PyThreadState_Current);
if (tstate != NULL && tstate->curexc_type != NULL) {
/* preserve the existing exception */
PyObject *err_type, *err_value, *err_tb;
PyErr_Fetch(&err_type, &err_value, &err_tb);
ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr);
/* ignore errors */
PyErr_Restore(err_type, err_value, err_tb);
if (ep == NULL)
return NULL;
}
else {
ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr);
if (ep == NULL) {
PyErr_Clear();
return NULL;
}
}
return *value_addr;
}
/* Variant of PyDict_GetItem() that doesn't suppress exceptions.
This returns NULL *with* an exception set if an exception occurred.
It returns NULL *without* an exception set if the key wasn't present.
......@@ -1207,6 +1245,24 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value)
return insertdict(mp, key, hash, value);
}
int
_PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
Py_hash_t hash)
{
PyDictObject *mp;
if (!PyDict_Check(op)) {
PyErr_BadInternalCall();
return -1;
}
assert(key);
assert(value);
mp = (PyDictObject *)op;
/* insertdict() handles any resizing that might be necessary */
return insertdict(mp, key, hash, value);
}
int
PyDict_DelItem(PyObject *op, PyObject *key)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment