summaryrefslogtreecommitdiff
path: root/Objects/setobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/setobject.c')
-rw-r--r--Objects/setobject.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 0f6c9022a5..2210edf787 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -932,14 +932,31 @@ set_update_internal(PySetObject *so, PyObject *other)
{
PyObject *key, *it;
- if (PyAnySet_Check(other))
+ if (PyAnySet_CheckExact(other))
return set_merge(so, other);
if (PyDict_CheckExact(other)) {
PyObject *value;
Py_ssize_t pos = 0;
- while (PyDict_Next(other, &pos, &key, &value)) {
- if (set_add_key(so, key) == -1)
+ long hash;
+ Py_ssize_t dictsize = PyDict_Size(other);
+
+ /* Do one big resize at the start, rather than
+ * incrementally resizing as we insert new keys. Expect
+ * that there will be no (or few) overlapping keys.
+ */
+ if (dictsize == -1)
+ return -1;
+ if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {
+ if (set_table_resize(so, (so->used + dictsize)*2) != 0)
+ return -1;
+ }
+ while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
+ setentry an_entry;
+
+ an_entry.hash = hash;
+ an_entry.key = key;
+ if (set_add_entry(so, &an_entry) == -1)
return -1;
}
return 0;
@@ -1210,7 +1227,7 @@ set_intersection(PySetObject *so, PyObject *other)
if (result == NULL)
return NULL;
- if (PyAnySet_Check(other)) {
+ if (PyAnySet_CheckExact(other)) {
Py_ssize_t pos = 0;
setentry *entry;
@@ -1334,7 +1351,7 @@ set_difference_update_internal(PySetObject *so, PyObject *other)
if ((PyObject *)so == other)
return set_clear_internal(so);
- if (PyAnySet_Check(other)) {
+ if (PyAnySet_CheckExact(other)) {
setentry *entry;
Py_ssize_t pos = 0;
@@ -1383,7 +1400,7 @@ set_difference(PySetObject *so, PyObject *other)
setentry *entry;
Py_ssize_t pos = 0;
- if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
+ if (!PyAnySet_CheckExact(other) && !PyDict_CheckExact(other)) {
result = set_copy(so);
if (result == NULL)
return NULL;
@@ -1402,7 +1419,7 @@ set_difference(PySetObject *so, PyObject *other)
setentry entrycopy;
entrycopy.hash = entry->hash;
entrycopy.key = entry->key;
- if (!PyDict_Contains(other, entry->key)) {
+ if (!_PyDict_Contains(other, entry->key, entry->hash)) {
if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
Py_DECREF(result);
return NULL;
@@ -1473,12 +1490,10 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
if (PyDict_CheckExact(other)) {
PyObject *value;
int rv;
- while (PyDict_Next(other, &pos, &key, &value)) {
+ long hash;
+ while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
setentry an_entry;
- long hash = PyObject_Hash(key);
- if (hash == -1)
- return NULL;
an_entry.hash = hash;
an_entry.key = key;
rv = set_discard_entry(so, &an_entry);
@@ -1492,7 +1507,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
Py_RETURN_NONE;
}
- if (PyAnySet_Check(other)) {
+ if (PyAnySet_CheckExact(other)) {
Py_INCREF(other);
otherset = (PySetObject *)other;
} else {
@@ -1575,7 +1590,7 @@ set_issubset(PySetObject *so, PyObject *other)
setentry *entry;
Py_ssize_t pos = 0;
- if (!PyAnySet_Check(other)) {
+ if (!PyAnySet_CheckExact(other)) {
PyObject *tmp, *result;
tmp = make_new_set(&PySet_Type, other);
if (tmp == NULL)
@@ -1604,7 +1619,7 @@ set_issuperset(PySetObject *so, PyObject *other)
{
PyObject *tmp, *result;
- if (!PyAnySet_Check(other)) {
+ if (!PyAnySet_CheckExact(other)) {
tmp = make_new_set(&PySet_Type, other);
if (tmp == NULL)
return NULL;