summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/setobject.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2022-04-18 12:39:32 +0300
committershadchin <[email protected]>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Objects/setobject.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff)
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Objects/setobject.c')
-rw-r--r--contrib/tools/python3/src/Objects/setobject.c68
1 files changed, 30 insertions, 38 deletions
diff --git a/contrib/tools/python3/src/Objects/setobject.c b/contrib/tools/python3/src/Objects/setobject.c
index 6d156bd4e08..e8ba32e5781 100644
--- a/contrib/tools/python3/src/Objects/setobject.c
+++ b/contrib/tools/python3/src/Objects/setobject.c
@@ -16,7 +16,7 @@
reduces the cost of hash collisions because consecutive memory accesses
tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
we then use more of the upper bits from the hash value and apply a simple
- linear congruential random number genearator. This helps break-up long
+ linear congruential random number generator. This helps break-up long
chains of collisions.
All arithmetic on hash should ignore overflow.
@@ -103,6 +103,7 @@ static int
set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
setentry *table;
+ setentry *freeslot;
setentry *entry;
size_t perturb;
size_t mask;
@@ -118,6 +119,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
mask = so->mask;
i = (size_t)hash & mask;
+ freeslot = NULL;
perturb = hash;
while (1) {
@@ -125,7 +127,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
do {
if (entry->hash == 0 && entry->key == NULL)
- goto found_unused;
+ goto found_unused_or_dummy;
if (entry->hash == hash) {
PyObject *startkey = entry->key;
assert(startkey != dummy);
@@ -147,12 +149,24 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
goto restart;
mask = so->mask;
}
+ else if (entry->hash == -1) {
+ assert (entry->key == dummy);
+ freeslot = entry;
+ }
entry++;
} while (probes--);
perturb >>= PERTURB_SHIFT;
i = (i * 5 + 1 + perturb) & mask;
}
+ found_unused_or_dummy:
+ if (freeslot == NULL)
+ goto found_unused;
+ so->used++;
+ freeslot->key = key;
+ freeslot->hash = hash;
+ return 0;
+
found_unused:
so->fill++;
so->used++;
@@ -289,7 +303,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
}
if (is_oldtable_malloced)
- PyMem_DEL(oldtable);
+ PyMem_Free(oldtable);
return 0;
}
@@ -424,7 +438,7 @@ set_clear_internal(PySetObject *so)
}
if (table_is_malloced)
- PyMem_DEL(table);
+ PyMem_Free(table);
return 0;
}
@@ -484,7 +498,7 @@ set_dealloc(PySetObject *so)
}
}
if (so->table != so->smalltable)
- PyMem_DEL(so->table);
+ PyMem_Free(so->table);
Py_TYPE(so)->tp_free(so);
Py_TRASHCAN_END
}
@@ -522,7 +536,7 @@ set_repr(PySetObject *so)
goto done;
listrepr = tmp;
- if (!Py_IS_TYPE(so, &PySet_Type))
+ if (!PySet_CheckExact(so))
result = PyUnicode_FromFormat("%s({%U})",
Py_TYPE(so)->tp_name,
listrepr);
@@ -975,9 +989,6 @@ make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
return make_new_set(type, iterable);
}
-/* The empty frozenset is a singleton */
-static PyObject *emptyfrozenset = NULL;
-
static PyObject *
make_new_frozenset(PyTypeObject *type, PyObject *iterable)
{
@@ -985,26 +996,12 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable)
return make_new_set(type, iterable);
}
- if (iterable != NULL) {
- if (PyFrozenSet_CheckExact(iterable)) {
- /* frozenset(f) is idempotent */
- Py_INCREF(iterable);
- return iterable;
- }
- PyObject *res = make_new_set((PyTypeObject *)type, iterable);
- if (res == NULL || PySet_GET_SIZE(res) != 0) {
- return res;
- }
- /* If the created frozenset is empty, return the empty frozenset singleton instead */
- Py_DECREF(res);
- }
-
- // The empty frozenset is a singleton
- if (emptyfrozenset == NULL) {
- emptyfrozenset = make_new_set((PyTypeObject *)type, NULL);
+ if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
+ /* frozenset(f) is idempotent */
+ Py_INCREF(iterable);
+ return iterable;
}
- Py_XINCREF(emptyfrozenset);
- return emptyfrozenset;
+ return make_new_set((PyTypeObject *)type, iterable);
}
static PyObject *
@@ -1530,7 +1527,7 @@ set_difference(PySetObject *so, PyObject *other)
key = entry->key;
hash = entry->hash;
Py_INCREF(key);
- rv = _PyDict_Contains(other, key, hash);
+ rv = _PyDict_Contains_KnownHash(other, key, hash);
if (rv < 0) {
Py_DECREF(result);
Py_DECREF(key);
@@ -2141,7 +2138,8 @@ PyTypeObject PySet_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_BASETYPE |
+ _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
set_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */
(inquiry)set_clear_internal, /* tp_clear */
@@ -2241,7 +2239,8 @@ PyTypeObject PyFrozenSet_Type = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_BASETYPE |
+ _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
frozenset_doc, /* tp_doc */
(traverseproc)set_traverse, /* tp_traverse */
(inquiry)set_clear_internal, /* tp_clear */
@@ -2330,12 +2329,6 @@ PySet_Add(PyObject *anyset, PyObject *key)
return set_add_key((PySetObject *)anyset, key);
}
-void
-_PySet_Fini(void)
-{
- Py_CLEAR(emptyfrozenset);
-}
-
int
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
@@ -2558,4 +2551,3 @@ static PyObject _dummy_struct = {
_PyObject_EXTRA_INIT
2, &_PySetDummy_Type
};
-