mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.14] gh-132657: avoid locks and refcounting in frozenset lookups (GH-136107) (gh-141772)
gh-132657: avoid locks and refcounting in `frozenset` lookups (GH-136107)
(cherry picked from commit f58a7c7175)
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
This commit is contained in:
parent
f6552d2c58
commit
c05e71f61e
2 changed files with 26 additions and 10 deletions
|
|
@ -86,6 +86,8 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||
int probes;
|
||||
int cmp;
|
||||
|
||||
int frozenset = PyFrozenSet_CheckExact(so);
|
||||
|
||||
while (1) {
|
||||
entry = &so->table[i];
|
||||
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
|
||||
|
|
@ -102,13 +104,20 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
|
|||
&& unicode_eq(startkey, key))
|
||||
return entry;
|
||||
table = so->table;
|
||||
Py_INCREF(startkey);
|
||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||
Py_DECREF(startkey);
|
||||
if (cmp < 0)
|
||||
return NULL;
|
||||
if (table != so->table || entry->key != startkey)
|
||||
return set_lookkey(so, key, hash);
|
||||
if (frozenset) {
|
||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||
if (cmp < 0)
|
||||
return NULL;
|
||||
} else {
|
||||
// incref startkey because it can be removed from the set by the compare
|
||||
Py_INCREF(startkey);
|
||||
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
|
||||
Py_DECREF(startkey);
|
||||
if (cmp < 0)
|
||||
return NULL;
|
||||
if (table != so->table || entry->key != startkey)
|
||||
return set_lookkey(so, key, hash);
|
||||
}
|
||||
if (cmp > 0)
|
||||
return entry;
|
||||
mask = so->mask;
|
||||
|
|
@ -2234,10 +2243,16 @@ set_contains_lock_held(PySetObject *so, PyObject *key)
|
|||
int
|
||||
_PySet_Contains(PySetObject *so, PyObject *key)
|
||||
{
|
||||
assert(so);
|
||||
|
||||
int rv;
|
||||
Py_BEGIN_CRITICAL_SECTION(so);
|
||||
rv = set_contains_lock_held(so, key);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
if (PyFrozenSet_CheckExact(so)) {
|
||||
rv = set_contains_lock_held(so, key);
|
||||
} else {
|
||||
Py_BEGIN_CRITICAL_SECTION(so);
|
||||
rv = set_contains_lock_held(so, key);
|
||||
Py_END_CRITICAL_SECTION();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue