diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-10-02 09:47:11 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-10-02 09:47:11 (GMT) |
commit | b9d98d532cb9bdebff9854eaff91fea13769a595 (patch) | |
tree | 5903bef16674011ec23f91dc4abccaf54777b23e /Objects/dictobject.c | |
parent | c9fda9b903dc85be334e588b4be784e878248905 (diff) | |
download | cpython-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.c | 37 |
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) { |