Kaydet (Commit) ff9e18a8 authored tarafından Raymond Hettinger's avatar Raymond Hettinger

Issue #24583: Consolidate previous set object updates into a single function

with a single entry point, named exit points at the bottom, more self-evident
refcount adjustments, and a comment describing why the pre-increment was
necessary at all.
üst aa23fa2e
...@@ -127,17 +127,27 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) ...@@ -127,17 +127,27 @@ set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
static int set_table_resize(PySetObject *, Py_ssize_t); static int set_table_resize(PySetObject *, Py_ssize_t);
static int static int
_set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{ {
setentry *table = so->table; setentry *table;
setentry *freeslot; setentry *freeslot;
setentry *entry; setentry *entry;
size_t perturb; size_t perturb;
size_t mask = so->mask; size_t mask;
size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */ size_t i; /* Unsigned for defined overflow behavior */
size_t j; size_t j;
int cmp; int cmp;
/* Pre-increment is necessary to prevent arbitrary code in the rich
comparison from deallocating the key just before the insertion. */
Py_INCREF(key);
restart:
table = so->table;
mask = so->mask;
i = (size_t)hash & mask;
entry = &table[i]; entry = &table[i];
if (entry->key == NULL) if (entry->key == NULL)
goto found_unused; goto found_unused;
...@@ -160,9 +170,9 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) ...@@ -160,9 +170,9 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
Py_DECREF(startkey); Py_DECREF(startkey);
if (cmp < 0) /* unlikely */ if (cmp < 0) /* unlikely */
return -1; goto comparison_error;
if (table != so->table || entry->key != startkey) /* unlikely */ if (table != so->table || entry->key != startkey) /* unlikely */
return _set_add_entry(so, key, hash); goto restart;
if (cmp > 0) /* likely */ if (cmp > 0) /* likely */
goto found_active; goto found_active;
mask = so->mask; /* help avoid a register spill */ mask = so->mask; /* help avoid a register spill */
...@@ -188,9 +198,9 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) ...@@ -188,9 +198,9 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
Py_DECREF(startkey); Py_DECREF(startkey);
if (cmp < 0) if (cmp < 0)
return -1; goto comparison_error;
if (table != so->table || entry->key != startkey) if (table != so->table || entry->key != startkey)
return _set_add_entry(so, key, hash); goto restart;
if (cmp > 0) if (cmp > 0)
goto found_active; goto found_active;
mask = so->mask; mask = so->mask;
...@@ -223,22 +233,13 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) ...@@ -223,22 +233,13 @@ _set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
entry->hash = hash; entry->hash = hash;
if ((size_t)so->fill*3 < mask*2) if ((size_t)so->fill*3 < mask*2)
return 0; return 0;
if (!set_table_resize(so, so->used)) return set_table_resize(so, so->used);
return 0;
Py_INCREF(key);
return -1;
found_active: found_active:
Py_DECREF(key); Py_DECREF(key);
return 0; return 0;
}
static int comparison_error:
set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
Py_INCREF(key);
if (!_set_add_entry(so, key, hash))
return 0;
Py_DECREF(key); Py_DECREF(key);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment