diff options
| author | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
| commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
| tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Objects/setobject.c | |
| parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (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.c | 68 |
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 }; - |
