Skip to content

Commit e630b64

Browse files
committed
Avoid locks are and refcounts in frozenset operatins
1 parent c419af9 commit e630b64

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

Objects/setobject.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
8585
int probes;
8686
int cmp;
8787

88+
int frozenset = PyFrozenSet_CheckExact(so);
89+
8890
while (1) {
8991
entry = &so->table[i];
9092
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
@@ -101,9 +103,14 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
101103
&& unicode_eq(startkey, key))
102104
return entry;
103105
table = so->table;
104-
Py_INCREF(startkey);
105-
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
106-
Py_DECREF(startkey);
106+
if (frozenset) {
107+
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
108+
} else {
109+
// incref startkey because it can be removed from the set by the compare
110+
Py_INCREF(startkey);
111+
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
112+
Py_DECREF(startkey);
113+
}
107114
if (cmp < 0)
108115
return NULL;
109116
if (table != so->table || entry->key != startkey)
@@ -2234,10 +2241,16 @@ set_contains_lock_held(PySetObject *so, PyObject *key)
22342241
int
22352242
_PySet_Contains(PySetObject *so, PyObject *key)
22362243
{
2244+
assert(so);
2245+
22372246
int rv;
2238-
Py_BEGIN_CRITICAL_SECTION(so);
2239-
rv = set_contains_lock_held(so, key);
2240-
Py_END_CRITICAL_SECTION();
2247+
if (PyFrozenSet_CheckExact(so)) {
2248+
rv = set_contains_lock_held(so, key);
2249+
} else {
2250+
Py_BEGIN_CRITICAL_SECTION(so);
2251+
rv = set_contains_lock_held(so, key);
2252+
Py_END_CRITICAL_SECTION();
2253+
}
22412254
return rv;
22422255
}
22432256

0 commit comments

Comments
 (0)