summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2014-05-03 23:32:11 (GMT)
committerRaymond Hettinger <python@rcn.com>2014-05-03 23:32:11 (GMT)
commit4b74fba62ff9e9733da01a55d4091b656324e969 (patch)
tree3cec3f8e3aac0f6f0e3fb30e1fa06c11c6a4e746 /Objects
parent1b5eebcfa3e5d21c14e89dc7e5bf2d124f8710a2 (diff)
downloadcpython-4b74fba62ff9e9733da01a55d4091b656324e969.zip
cpython-4b74fba62ff9e9733da01a55d4091b656324e969.tar.gz
cpython-4b74fba62ff9e9733da01a55d4091b656324e969.tar.bz2
Issue 21101: Internal API for dict getitem and setitem where the hash value is known.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/dictobject.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 1ccea6e..6c78b94 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -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.
@@ -1208,6 +1246,24 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *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)
{
PyDictObject *mp;