summaryrefslogtreecommitdiffstats
path: root/Objects/dictobject.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-10-02 09:47:11 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-10-02 09:47:11 (GMT)
commitb9d98d532cb9bdebff9854eaff91fea13769a595 (patch)
tree5903bef16674011ec23f91dc4abccaf54777b23e /Objects/dictobject.c
parentc9fda9b903dc85be334e588b4be784e878248905 (diff)
downloadcpython-b9d98d532cb9bdebff9854eaff91fea13769a595.zip
cpython-b9d98d532cb9bdebff9854eaff91fea13769a595.tar.gz
cpython-b9d98d532cb9bdebff9854eaff91fea13769a595.tar.bz2
Issue #24483: C implementation of functools.lru_cache() now calculates key's
hash only once.
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r--Objects/dictobject.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 5a7de9e..624ae9b 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1242,6 +1242,7 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value,
}
assert(key);
assert(value);
+ assert(hash != -1);
mp = (PyDictObject *)op;
/* insertdict() handles any resizing that might be necessary */
@@ -1290,6 +1291,42 @@ PyDict_DelItem(PyObject *op, PyObject *key)
return 0;
}
+int
+_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
+{
+ PyDictObject *mp;
+ PyDictKeyEntry *ep;
+ PyObject *old_key, *old_value;
+ PyObject **value_addr;
+
+ if (!PyDict_Check(op)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ assert(key);
+ assert(hash != -1);
+ mp = (PyDictObject *)op;
+ ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr);
+ if (ep == NULL)
+ return -1;
+ if (*value_addr == NULL) {
+ _PyErr_SetKeyError(key);
+ return -1;
+ }
+ old_value = *value_addr;
+ *value_addr = NULL;
+ mp->ma_used--;
+ if (!_PyDict_HasSplitTable(mp)) {
+ ENSURE_ALLOWS_DELETIONS(mp);
+ old_key = ep->me_key;
+ Py_INCREF(dummy);
+ ep->me_key = dummy;
+ Py_DECREF(old_key);
+ }
+ Py_DECREF(old_value);
+ return 0;
+}
+
void
PyDict_Clear(PyObject *op)
{