blob: aa1f4eedbfd432f9d4fe3f34984d18a465d4f460 [file] [log] [blame]
Raymond Hettingerc991db22005-08-11 07:58:45 +00001
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002/* set object implementation
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07003
Raymond Hettingera9d99362005-08-05 00:01:15 +00004 Written and maintained by Raymond D. Hettinger <python@rcn.com>
5 Derived from Lib/sets.py and Objects/dictobject.c.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00006
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07007 The basic lookup function used by all operations.
8 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
9
10 The initial probe index is computed as hash mod the table size.
11 Subsequent probe indices are computed as explained in Objects/dictobject.c.
12
13 To improve cache locality, each probe inspects a series of consecutive
14 nearby entries before moving on to probes elsewhere in memory. This leaves
Raymond Hettinger64263df2017-09-04 18:54:16 -070015 us with a hybrid of linear probing and randomized probing. The linear probing
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070016 reduces the cost of hash collisions because consecutive memory accesses
17 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
Raymond Hettinger64263df2017-09-04 18:54:16 -070018 we then use more of the upper bits from the hash value and apply a simple
19 linear congruential random number genearator. This helps break-up long
20 chains of collisions.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070021
22 All arithmetic on hash should ignore overflow.
23
Raymond Hettinger4d45c102015-01-25 16:27:40 -080024 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070025 NULL if the rich comparison returns an error.
Serhiy Storchaka13ad3b72017-09-14 09:38:36 +030026
Raymond Hettinger64263df2017-09-04 18:54:16 -070027 Use cases for sets differ considerably from dictionaries where looked-up
28 keys are more likely to be present. In contrast, sets are primarily
29 about membership testing where the presence of an element is not known in
30 advance. Accordingly, the set implementation needs to optimize for both
31 the found and not-found case.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032*/
33
Raymond Hettingera690a992003-11-16 16:17:49 +000034#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -060035#include "internal/pystate.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000036#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050039static PyObject _dummy_struct;
40
41#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000042
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000043
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070044/* ======================================================================== */
45/* ======= Begin logic for probing the hash table ========================= */
46
Raymond Hettinger710a67e2013-09-21 20:17:31 -070047/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070048#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070049#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070050#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070051
52/* This must be >= 1 */
53#define PERTURB_SHIFT 5
54
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000055static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000057{
Raymond Hettinger70559b52015-07-23 07:42:23 -040058 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020059 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070060 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070061 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080062 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070063 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070064 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000065
Raymond Hettinger70559b52015-07-23 07:42:23 -040066 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070067 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070069
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070070 perturb = hash;
71
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070072 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080073 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070074 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080075 /* startkey cannot be a dummy because the dummy hash field is -1 */
76 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080077 if (startkey == key)
78 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080079 if (PyUnicode_CheckExact(startkey)
80 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070081 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080082 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040083 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 Py_INCREF(startkey);
85 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
86 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010087 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010089 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010091 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070092 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060093 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070094 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070095
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080097 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080098 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070099 if (entry->hash == 0 && entry->key == NULL)
100 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800101 if (entry->hash == hash) {
102 PyObject *startkey = entry->key;
103 assert(startkey != dummy);
104 if (startkey == key)
105 return entry;
106 if (PyUnicode_CheckExact(startkey)
107 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700108 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800109 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400110 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800111 Py_INCREF(startkey);
112 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
113 Py_DECREF(startkey);
114 if (cmp < 0)
115 return NULL;
116 if (table != so->table || entry->key != startkey)
117 return set_lookkey(so, key, hash);
118 if (cmp > 0)
119 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600120 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800121 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700122 }
123 }
124
125 perturb >>= PERTURB_SHIFT;
126 i = (i * 5 + 1 + perturb) & mask;
127
Raymond Hettinger70559b52015-07-23 07:42:23 -0400128 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700129 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700130 return entry;
131 }
132}
133
Raymond Hettinger15f08692015-07-03 17:21:17 -0700134static int set_table_resize(PySetObject *, Py_ssize_t);
135
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400137set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700138{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400139 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700140 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700141 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700142 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 size_t mask;
144 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700145 size_t j;
146 int cmp;
147
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400148 /* Pre-increment is necessary to prevent arbitrary code in the rich
149 comparison from deallocating the key just before the insertion. */
150 Py_INCREF(key);
151
152 restart:
153
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400154 mask = so->mask;
155 i = (size_t)hash & mask;
156
Raymond Hettinger70559b52015-07-23 07:42:23 -0400157 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700159 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700160
161 freeslot = NULL;
162 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700163
164 while (1) {
165 if (entry->hash == hash) {
166 PyObject *startkey = entry->key;
167 /* startkey cannot be a dummy because the dummy hash field is -1 */
168 assert(startkey != dummy);
169 if (startkey == key)
170 goto found_active;
171 if (PyUnicode_CheckExact(startkey)
172 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700173 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400175 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700176 Py_INCREF(startkey);
177 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
178 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700179 if (cmp > 0) /* likely */
180 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700181 if (cmp < 0)
182 goto comparison_error;
183 /* Continuing the search from the current entry only makes
184 sense if the table and entry are unchanged; otherwise,
185 we have to restart from the beginning */
186 if (table != so->table || entry->key != startkey)
187 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700188 mask = so->mask; /* help avoid a register spill */
189 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800190 else if (entry->hash == -1)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700191 freeslot = entry;
192
193 if (i + LINEAR_PROBES <= mask) {
194 for (j = 0 ; j < LINEAR_PROBES ; j++) {
195 entry++;
196 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700197 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700198 if (entry->hash == hash) {
199 PyObject *startkey = entry->key;
200 assert(startkey != dummy);
201 if (startkey == key)
202 goto found_active;
203 if (PyUnicode_CheckExact(startkey)
204 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700205 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700206 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400207 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 Py_INCREF(startkey);
209 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
210 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700211 if (cmp > 0)
212 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700213 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400214 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700215 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400216 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700217 mask = so->mask;
218 }
Raymond Hettinger33299922018-01-14 10:20:13 -0800219 else if (entry->hash == -1)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800220 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700221 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700223
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700224 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800225 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700226
Raymond Hettinger70559b52015-07-23 07:42:23 -0400227 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700228 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700229 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700231
Raymond Hettinger15f08692015-07-03 17:21:17 -0700232 found_unused_or_dummy:
233 if (freeslot == NULL)
234 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700235 so->used++;
236 freeslot->key = key;
237 freeslot->hash = hash;
238 return 0;
239
240 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700241 so->fill++;
242 so->used++;
243 entry->key = key;
244 entry->hash = hash;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800245 if ((size_t)so->fill*5 < mask*3)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700246 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +0900247 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700248
249 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400250 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700251 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000252
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400253 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700254 Py_DECREF(key);
255 return -1;
256}
257
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000258/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000259Internal routine used by set_table_resize() to insert an item which is
260known to be absent from the set. This routine also assumes that
261the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800262there is also safety benefit since using set_add_entry() risks making
263a callback in the middle of a set_table_resize(), see issue 1456209.
264The caller is responsible for updating the key's reference count and
265the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000266*/
267static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800268set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200270 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700271 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800272 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700273 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700275 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800276 entry = &table[i];
277 if (entry->key == NULL)
278 goto found_null;
279 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800280 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800281 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800282 if (entry->key == NULL)
283 goto found_null;
284 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700285 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700286 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800287 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700289 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800290 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800291 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292}
293
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700294/* ======== End logic for probing the hash table ========================== */
295/* ======================================================================== */
296
Thomas Wouters89f507f2006-12-13 04:49:30 +0000297/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000298Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000299keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000300actually be smaller than the old one.
301*/
302static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 setentry *oldtable, *newtable, *entry;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800306 Py_ssize_t oldmask = so->mask;
307 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 int is_oldtable_malloced;
309 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100314 /* XXX speed-up with intrinsics */
Sergey Fedoseev6c7d67c2018-09-12 04:18:01 +0500315 size_t newsize = PySet_MINSIZE;
316 while (newsize <= (size_t)minused) {
317 newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 /* Get space for a new table. */
321 oldtable = so->table;
322 assert(oldtable != NULL);
323 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (newsize == PySet_MINSIZE) {
326 /* A large table is shrinking, or we can't get any smaller. */
327 newtable = so->smalltable;
328 if (newtable == oldtable) {
329 if (so->fill == so->used) {
330 /* No dummies, so no point doing anything. */
331 return 0;
332 }
333 /* We're not going to resize it, but rebuild the
334 table anyway to purge old dummy entries.
335 Subtle: This is *necessary* if fill==size,
336 as set_lookkey needs at least one virgin slot to
337 terminate failing searches. If fill < size, it's
338 merely desirable, as dummies slow searches. */
339 assert(so->fill > so->used);
340 memcpy(small_copy, oldtable, sizeof(small_copy));
341 oldtable = small_copy;
342 }
343 }
344 else {
345 newtable = PyMem_NEW(setentry, newsize);
346 if (newtable == NULL) {
347 PyErr_NoMemory();
348 return -1;
349 }
350 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 /* Make the set empty, using the new table. */
353 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800355 so->mask = newsize - 1;
356 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 /* Copy the data over; this is refcount-neutral for active entries;
359 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800360 newmask = (size_t)so->mask;
Raymond Hettingere1af6962017-02-02 08:24:48 -0800361 if (so->fill == so->used) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800362 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800363 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800364 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800365 }
366 }
367 } else {
Raymond Hettingere1af6962017-02-02 08:24:48 -0800368 so->fill = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800371 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800372 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 }
374 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 if (is_oldtable_malloced)
377 PyMem_DEL(oldtable);
378 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379}
380
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000381static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700382set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700384 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386 entry = set_lookkey(so, key, hash);
387 if (entry != NULL)
388 return entry->key != NULL;
389 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000390}
391
392#define DISCARD_NOTFOUND 0
393#define DISCARD_FOUND 1
394
395static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700396set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800397{
398 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000400
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700401 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 if (entry == NULL)
403 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700404 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return DISCARD_NOTFOUND;
406 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800408 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 so->used--;
410 Py_DECREF(old_key);
411 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000412}
413
414static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700415set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000416{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200417 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000418
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419 if (!PyUnicode_CheckExact(key) ||
420 (hash = ((PyASCIIObject *) key)->hash) == -1) {
421 hash = PyObject_Hash(key);
422 if (hash == -1)
423 return -1;
424 }
425 return set_add_entry(so, key, hash);
426}
427
428static int
429set_contains_key(PySetObject *so, PyObject *key)
430{
431 Py_hash_t hash;
432
433 if (!PyUnicode_CheckExact(key) ||
434 (hash = ((PyASCIIObject *) key)->hash) == -1) {
435 hash = PyObject_Hash(key);
436 if (hash == -1)
437 return -1;
438 }
439 return set_contains_entry(so, key, hash);
440}
441
442static int
443set_discard_key(PySetObject *so, PyObject *key)
444{
445 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 hash = PyObject_Hash(key);
450 if (hash == -1)
451 return -1;
452 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700453 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000454}
455
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700456static void
457set_empty_to_minsize(PySetObject *so)
458{
459 memset(so->smalltable, 0, sizeof(so->smalltable));
460 so->fill = 0;
461 so->used = 0;
462 so->mask = PySet_MINSIZE - 1;
463 so->table = so->smalltable;
464 so->hash = -1;
465}
466
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000467static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000468set_clear_internal(PySetObject *so)
469{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800470 setentry *entry;
471 setentry *table = so->table;
472 Py_ssize_t fill = so->fill;
473 Py_ssize_t used = so->used;
474 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000476
Raymond Hettinger583cd032013-09-07 22:06:35 -0700477 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000479
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 /* This is delicate. During the process of clearing the set,
481 * decrefs can cause the set to mutate. To avoid fatal confusion
482 * (voice of experience), we have to make the set empty before
483 * clearing the slots, and never refer to anything via so->ref while
484 * clearing.
485 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700487 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 else if (fill > 0) {
490 /* It's a small table with something that needs to be cleared.
491 * Afraid the only safe way is to copy the set entries into
492 * another small table first.
493 */
494 memcpy(small_copy, table, sizeof(small_copy));
495 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700496 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 }
498 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Now we can finally clear things. If C had refcounts, we could
501 * assert that the refcount on table is 1 now, i.e. that this function
502 * has unique access to it, so decref side-effects can't alter it.
503 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800504 for (entry = table; used > 0; entry++) {
505 if (entry->key && entry->key != dummy) {
506 used--;
507 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 if (table_is_malloced)
512 PyMem_DEL(table);
513 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514}
515
516/*
517 * Iterate over a set table. Use like so:
518 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000520 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000521 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000522 * while (set_next(yourset, &pos, &entry)) {
523 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000524 * }
525 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 */
529static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000530set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000531{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 Py_ssize_t i;
533 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700534 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 assert (PyAnySet_Check(so));
537 i = *pos_ptr;
538 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700540 entry = &so->table[i];
541 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700543 entry++;
544 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 *pos_ptr = i+1;
546 if (i > mask)
547 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700548 assert(entry != NULL);
549 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000551}
552
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000553static void
554set_dealloc(PySetObject *so)
555{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200556 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800557 Py_ssize_t used = so->used;
558
INADA Naokia6296d32017-08-24 14:55:17 +0900559 /* bpo-31095: UnTrack is needed before calling any callbacks */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 PyObject_GC_UnTrack(so);
561 Py_TRASHCAN_SAFE_BEGIN(so)
562 if (so->weakreflist != NULL)
563 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000564
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800565 for (entry = so->table; used > 0; entry++) {
566 if (entry->key && entry->key != dummy) {
567 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700568 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 }
570 }
571 if (so->table != so->smalltable)
572 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700573 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000575}
576
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000577static PyObject *
578set_repr(PySetObject *so)
579{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200580 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 if (status != 0) {
584 if (status < 0)
585 return NULL;
586 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
587 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 /* shortcut for the empty set */
590 if (!so->used) {
591 Py_ReprLeave((PyObject*)so);
592 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
593 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 keys = PySequence_List((PyObject *)so);
596 if (keys == NULL)
597 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000598
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200599 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 listrepr = PyObject_Repr(keys);
601 Py_DECREF(keys);
602 if (listrepr == NULL)
603 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200604 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200606 if (tmp == NULL)
607 goto done;
608 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200609
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200610 if (Py_TYPE(so) != &PySet_Type)
611 result = PyUnicode_FromFormat("%s({%U})",
612 Py_TYPE(so)->tp_name,
613 listrepr);
614 else
615 result = PyUnicode_FromFormat("{%U}", listrepr);
616 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000617done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 Py_ReprLeave((PyObject*)so);
619 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000620}
621
Martin v. Löwis18e16552006-02-15 17:27:45 +0000622static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623set_len(PyObject *so)
624{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000626}
627
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000628static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000629set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000632 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200633 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700634 setentry *so_entry;
635 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 assert (PyAnySet_Check(so));
638 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 other = (PySetObject*)otherset;
641 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700642 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return 0;
644 /* Do one big resize at the start, rather than
645 * incrementally resizing as we insert new keys. Expect
646 * that there will be no (or few) overlapping keys.
647 */
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800648 if ((so->fill + other->used)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900649 if (set_table_resize(so, (so->used + other->used)*2) != 0)
650 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700652 so_entry = so->table;
653 other_entry = other->table;
654
655 /* If our table is empty, and both tables have the same size, and
656 there are no dummies to eliminate, then just copy the pointers. */
657 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
658 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
659 key = other_entry->key;
660 if (key != NULL) {
661 assert(so_entry->key == NULL);
662 Py_INCREF(key);
663 so_entry->key = key;
664 so_entry->hash = other_entry->hash;
665 }
666 }
667 so->fill = other->fill;
668 so->used = other->used;
669 return 0;
670 }
671
672 /* If our table is empty, we can use set_insert_clean() */
673 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800674 setentry *newtable = so->table;
675 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800676 so->fill = other->used;
677 so->used = other->used;
Raymond Hettingere4495872015-12-15 00:42:30 -0800678 for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700679 key = other_entry->key;
680 if (key != NULL && key != dummy) {
681 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800682 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700683 }
684 }
685 return 0;
686 }
687
688 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700689 for (i = 0; i <= other->mask; i++) {
690 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700691 key = other_entry->key;
692 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700693 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 }
696 }
697 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000698}
699
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000700static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530701set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000702{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800703 /* Make sure the search finger is in bounds */
704 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200705 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000707
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000708 assert (PyAnySet_Check(so));
709 if (so->used == 0) {
710 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
711 return NULL;
712 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000713
Raymond Hettinger1202a472015-01-18 13:12:42 -0800714 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
715 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800716 if (i > so->mask)
717 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 }
719 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800721 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800723 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000725}
726
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000727PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
728Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000729
730static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000731set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 Py_ssize_t pos = 0;
734 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000735
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 while (set_next(so, &pos, &entry))
737 Py_VISIT(entry->key);
738 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000739}
740
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700741/* Work to increase the bit dispersion for closely spaced hash values.
742 This is important because some use cases have many combinations of a
743 small number of elements with nearby hashes so that many distinct
744 combinations collapse to only a handful of distinct hash values. */
745
746static Py_uhash_t
747_shuffle_bits(Py_uhash_t h)
748{
749 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
750}
751
752/* Most of the constants in this hash algorithm are randomly chosen
753 large primes with "interesting bit patterns" and that passed tests
754 for good collision statistics on a variety of problematic datasets
755 including powersets and graph structures (such as David Eppstein's
756 graph recipes in Lib/test/test_set.py) */
757
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000758static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000759frozenset_hash(PyObject *self)
760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700762 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000764
Raymond Hettingerb501a272015-08-06 22:15:22 -0700765 if (so->hash != -1)
766 return so->hash;
767
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700768 /* Xor-in shuffled bits from every entry's hash field because xor is
769 commutative and a frozenset hash should be independent of order.
770
771 For speed, include null entries and dummy entries and then
772 subtract out their effect afterwards so that the final hash
773 depends only on active entries. This allows the code to be
774 vectorized by the compiler and it saves the unpredictable
775 branches that would arise when trying to exclude null and dummy
776 entries on every iteration. */
777
778 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
779 hash ^= _shuffle_bits(entry->hash);
780
Raymond Hettingera286a512015-08-01 11:07:11 -0700781 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700782 if ((so->mask + 1 - so->fill) & 1)
783 hash ^= _shuffle_bits(0);
784
785 /* Remove the effect of an odd number of dummy entries */
786 if ((so->fill - so->used) & 1)
787 hash ^= _shuffle_bits(-1);
788
Raymond Hettinger41481952015-08-07 00:43:39 -0700789 /* Factor in the number of active entries */
790 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
791
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700792 /* Disperse patterns arising in nested frozensets */
Raymond Hettingerfa788062018-01-18 13:23:27 -0800793 hash ^= (hash >> 11) ^ (hash >> 25);
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800794 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700795
Raymond Hettinger36c05002015-08-01 10:57:42 -0700796 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200797 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800798 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 so->hash = hash;
801 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000802}
803
Raymond Hettingera9d99362005-08-05 00:01:15 +0000804/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000805
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000806typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 PyObject_HEAD
808 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
809 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700810 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000812} setiterobject;
813
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000814static void
815setiter_dealloc(setiterobject *si)
816{
INADA Naokia6296d32017-08-24 14:55:17 +0900817 /* bpo-31095: UnTrack is needed before calling any callbacks */
818 _PyObject_GC_UNTRACK(si);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 Py_XDECREF(si->si_set);
820 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000821}
822
823static int
824setiter_traverse(setiterobject *si, visitproc visit, void *arg)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 Py_VISIT(si->si_set);
827 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000828}
829
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000830static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530831setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000832{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 Py_ssize_t len = 0;
834 if (si->si_set != NULL && si->si_used == si->si_set->used)
835 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000836 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000837}
838
Armin Rigof5b3e362006-02-11 21:32:43 +0000839PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000840
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000841static PyObject *setiter_iternext(setiterobject *si);
842
843static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530844setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000845{
Ezio Melotti0e1af282012-09-28 16:43:40 +0300846 /* copy the iterator state */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500847 setiterobject tmp = *si;
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000848 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300849
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000850 /* iterate the temporary into a list */
Sergey Fedoseev63958442018-10-20 05:43:33 +0500851 PyObject *list = PySequence_List((PyObject*)&tmp);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000852 Py_XDECREF(tmp.si_set);
Sergey Fedoseev63958442018-10-20 05:43:33 +0500853 if (list == NULL) {
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000854 return NULL;
855 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200856 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000857}
858
859PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
860
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000861static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000863 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000865};
866
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000867static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000868{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700869 PyObject *key;
870 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200871 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000872 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000873
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 if (so == NULL)
875 return NULL;
876 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 if (si->si_used != so->used) {
879 PyErr_SetString(PyExc_RuntimeError,
880 "Set changed size during iteration");
881 si->si_used = -1; /* Make this state sticky */
882 return NULL;
883 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700884
885 i = si->si_pos;
886 assert(i>=0);
887 entry = so->table;
888 mask = so->mask;
889 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
890 i++;
891 si->si_pos = i+1;
892 if (i > mask)
893 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700895 key = entry[i].key;
896 Py_INCREF(key);
897 return key;
898
899fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700900 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300901 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700902 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000903}
904
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000905PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 PyVarObject_HEAD_INIT(&PyType_Type, 0)
907 "set_iterator", /* tp_name */
908 sizeof(setiterobject), /* tp_basicsize */
909 0, /* tp_itemsize */
910 /* methods */
911 (destructor)setiter_dealloc, /* tp_dealloc */
912 0, /* tp_print */
913 0, /* tp_getattr */
914 0, /* tp_setattr */
915 0, /* tp_reserved */
916 0, /* tp_repr */
917 0, /* tp_as_number */
918 0, /* tp_as_sequence */
919 0, /* tp_as_mapping */
920 0, /* tp_hash */
921 0, /* tp_call */
922 0, /* tp_str */
923 PyObject_GenericGetAttr, /* tp_getattro */
924 0, /* tp_setattro */
925 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700926 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 0, /* tp_doc */
928 (traverseproc)setiter_traverse, /* tp_traverse */
929 0, /* tp_clear */
930 0, /* tp_richcompare */
931 0, /* tp_weaklistoffset */
932 PyObject_SelfIter, /* tp_iter */
933 (iternextfunc)setiter_iternext, /* tp_iternext */
934 setiter_methods, /* tp_methods */
935 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000936};
937
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000938static PyObject *
939set_iter(PySetObject *so)
940{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
942 if (si == NULL)
943 return NULL;
944 Py_INCREF(so);
945 si->si_set = so;
946 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700947 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 si->len = so->used;
949 _PyObject_GC_TRACK(si);
950 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000951}
952
Raymond Hettingerd7946662005-08-01 21:39:29 +0000953static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000954set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 if (PyAnySet_Check(other))
959 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if (PyDict_CheckExact(other)) {
962 PyObject *value;
963 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000964 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200965 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 /* Do one big resize at the start, rather than
968 * incrementally resizing as we insert new keys. Expect
969 * that there will be no (or few) overlapping keys.
970 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700971 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800973 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900974 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 return -1;
976 }
977 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700978 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 return -1;
980 }
981 return 0;
982 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 it = PyObject_GetIter(other);
985 if (it == NULL)
986 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -0700989 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 Py_DECREF(it);
991 Py_DECREF(key);
992 return -1;
993 }
994 Py_DECREF(key);
995 }
996 Py_DECREF(it);
997 if (PyErr_Occurred())
998 return -1;
999 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001000}
1001
1002static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001003set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001004{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1008 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001009 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 return NULL;
1011 }
1012 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001013}
1014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001016"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001017
Raymond Hettinger426d9952014-05-18 21:40:20 +01001018/* XXX Todo:
1019 If aligned memory allocations become available, make the
1020 set object 64 byte aligned so that most of the fields
1021 can be retrieved or updated in a single cache line.
1022*/
1023
Raymond Hettingera38123e2003-11-24 22:18:49 +00001024static PyObject *
1025make_new_set(PyTypeObject *type, PyObject *iterable)
1026{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001027 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001028
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001029 so = (PySetObject *)type->tp_alloc(type, 0);
1030 if (so == NULL)
1031 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001032
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001033 so->fill = 0;
1034 so->used = 0;
1035 so->mask = PySet_MINSIZE - 1;
1036 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001037 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001038 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001042 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 Py_DECREF(so);
1044 return NULL;
1045 }
1046 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001049}
1050
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001051static PyObject *
1052make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1055 if (PyType_IsSubtype(type, &PySet_Type))
1056 type = &PySet_Type;
1057 else
1058 type = &PyFrozenSet_Type;
1059 }
1060 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001061}
1062
Raymond Hettingerd7946662005-08-01 21:39:29 +00001063/* The empty frozenset is a singleton */
1064static PyObject *emptyfrozenset = NULL;
1065
Raymond Hettingera690a992003-11-16 16:17:49 +00001066static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001067frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001070
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001071 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001073
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1075 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (type != &PyFrozenSet_Type)
1078 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001079
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 if (iterable != NULL) {
1081 /* frozenset(f) is idempotent */
1082 if (PyFrozenSet_CheckExact(iterable)) {
1083 Py_INCREF(iterable);
1084 return iterable;
1085 }
1086 result = make_new_set(type, iterable);
1087 if (result == NULL || PySet_GET_SIZE(result))
1088 return result;
1089 Py_DECREF(result);
1090 }
1091 /* The empty frozenset is a singleton */
1092 if (emptyfrozenset == NULL)
1093 emptyfrozenset = make_new_set(type, NULL);
1094 Py_XINCREF(emptyfrozenset);
1095 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001096}
1097
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001098static PyObject *
1099set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001102}
1103
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001104/* set_swap_bodies() switches the contents of any two sets by moving their
1105 internal data pointers and, if needed, copying the internal smalltables.
1106 Semantically equivalent to:
1107
1108 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1109
1110 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001111 Useful for operations that update in-place (by allowing an intermediate
1112 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001113*/
1114
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001115static void
1116set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001117{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 Py_ssize_t t;
1119 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001121 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 t = a->fill; a->fill = b->fill; b->fill = t;
1124 t = a->used; a->used = b->used; b->used = t;
1125 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 u = a->table;
1128 if (a->table == a->smalltable)
1129 u = b->smalltable;
1130 a->table = b->table;
1131 if (b->table == b->smalltable)
1132 a->table = a->smalltable;
1133 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001134
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 if (a->table == a->smalltable || b->table == b->smalltable) {
1136 memcpy(tab, a->smalltable, sizeof(tab));
1137 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1138 memcpy(b->smalltable, tab, sizeof(tab));
1139 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001140
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1142 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1143 h = a->hash; a->hash = b->hash; b->hash = h;
1144 } else {
1145 a->hash = -1;
1146 b->hash = -1;
1147 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001148}
1149
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001150static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301151set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001154}
1155
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001156static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301157frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 if (PyFrozenSet_CheckExact(so)) {
1160 Py_INCREF(so);
1161 return (PyObject *)so;
1162 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301163 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001164}
1165
Raymond Hettingera690a992003-11-16 16:17:49 +00001166PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1167
1168static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301169set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 set_clear_internal(so);
1172 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001173}
1174
1175PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1176
1177static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001178set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 PySetObject *result;
1181 PyObject *other;
1182 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001183
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301184 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 if (result == NULL)
1186 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1189 other = PyTuple_GET_ITEM(args, i);
1190 if ((PyObject *)so == other)
1191 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001192 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 Py_DECREF(result);
1194 return NULL;
1195 }
1196 }
1197 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001198}
1199
1200PyDoc_STRVAR(union_doc,
1201 "Return the union of sets as a new set.\n\
1202\n\
1203(i.e. all elements that are in either set.)");
1204
1205static PyObject *
1206set_or(PySetObject *so, PyObject *other)
1207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001209
Brian Curtindfc80e32011-08-10 20:28:54 -05001210 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1211 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001212
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301213 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 if (result == NULL)
1215 return NULL;
1216 if ((PyObject *)so == other)
1217 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001218 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 Py_DECREF(result);
1220 return NULL;
1221 }
1222 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001223}
1224
Raymond Hettingera690a992003-11-16 16:17:49 +00001225static PyObject *
1226set_ior(PySetObject *so, PyObject *other)
1227{
Brian Curtindfc80e32011-08-10 20:28:54 -05001228 if (!PyAnySet_Check(other))
1229 Py_RETURN_NOTIMPLEMENTED;
1230
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001231 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 return NULL;
1233 Py_INCREF(so);
1234 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001235}
1236
1237static PyObject *
1238set_intersection(PySetObject *so, PyObject *other)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 PySetObject *result;
1241 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001242 Py_hash_t hash;
1243 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301246 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1249 if (result == NULL)
1250 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 if (PyAnySet_Check(other)) {
1253 Py_ssize_t pos = 0;
1254 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1257 tmp = (PyObject *)so;
1258 so = (PySetObject *)other;
1259 other = tmp;
1260 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001263 key = entry->key;
1264 hash = entry->hash;
1265 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001266 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 Py_DECREF(result);
1268 return NULL;
1269 }
1270 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001271 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 Py_DECREF(result);
1273 return NULL;
1274 }
1275 }
1276 }
1277 return (PyObject *)result;
1278 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 it = PyObject_GetIter(other);
1281 if (it == NULL) {
1282 Py_DECREF(result);
1283 return NULL;
1284 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001287 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001288 if (hash == -1)
1289 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001290 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001291 if (rv < 0)
1292 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001294 if (set_add_entry(result, key, hash))
1295 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 }
1297 Py_DECREF(key);
1298 }
1299 Py_DECREF(it);
1300 if (PyErr_Occurred()) {
1301 Py_DECREF(result);
1302 return NULL;
1303 }
1304 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001305 error:
1306 Py_DECREF(it);
1307 Py_DECREF(result);
1308 Py_DECREF(key);
1309 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001310}
1311
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001312static PyObject *
1313set_intersection_multi(PySetObject *so, PyObject *args)
1314{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 Py_ssize_t i;
1316 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301319 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 Py_INCREF(so);
1322 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1323 PyObject *other = PyTuple_GET_ITEM(args, i);
1324 PyObject *newresult = set_intersection((PySetObject *)result, other);
1325 if (newresult == NULL) {
1326 Py_DECREF(result);
1327 return NULL;
1328 }
1329 Py_DECREF(result);
1330 result = newresult;
1331 }
1332 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001333}
1334
Raymond Hettingera690a992003-11-16 16:17:49 +00001335PyDoc_STRVAR(intersection_doc,
1336"Return the intersection of two sets as a new set.\n\
1337\n\
1338(i.e. all elements that are in both sets.)");
1339
1340static PyObject *
1341set_intersection_update(PySetObject *so, PyObject *other)
1342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 tmp = set_intersection(so, other);
1346 if (tmp == NULL)
1347 return NULL;
1348 set_swap_bodies(so, (PySetObject *)tmp);
1349 Py_DECREF(tmp);
1350 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001351}
1352
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001353static PyObject *
1354set_intersection_update_multi(PySetObject *so, PyObject *args)
1355{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 tmp = set_intersection_multi(so, args);
1359 if (tmp == NULL)
1360 return NULL;
1361 set_swap_bodies(so, (PySetObject *)tmp);
1362 Py_DECREF(tmp);
1363 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001364}
1365
Raymond Hettingera690a992003-11-16 16:17:49 +00001366PyDoc_STRVAR(intersection_update_doc,
1367"Update a set with the intersection of itself and another.");
1368
1369static PyObject *
1370set_and(PySetObject *so, PyObject *other)
1371{
Brian Curtindfc80e32011-08-10 20:28:54 -05001372 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1373 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001375}
1376
1377static PyObject *
1378set_iand(PySetObject *so, PyObject *other)
1379{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001381
Brian Curtindfc80e32011-08-10 20:28:54 -05001382 if (!PyAnySet_Check(other))
1383 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 result = set_intersection_update(so, other);
1385 if (result == NULL)
1386 return NULL;
1387 Py_DECREF(result);
1388 Py_INCREF(so);
1389 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001390}
1391
Guido van Rossum58da9312007-11-10 23:39:45 +00001392static PyObject *
1393set_isdisjoint(PySetObject *so, PyObject *other)
1394{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001396 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001398 if ((PyObject *)so == other) {
1399 if (PySet_GET_SIZE(so) == 0)
1400 Py_RETURN_TRUE;
1401 else
1402 Py_RETURN_FALSE;
1403 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001405 if (PyAnySet_CheckExact(other)) {
1406 Py_ssize_t pos = 0;
1407 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001408
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001409 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1410 tmp = (PyObject *)so;
1411 so = (PySetObject *)other;
1412 other = tmp;
1413 }
1414 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001415 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001416 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 return NULL;
1418 if (rv)
1419 Py_RETURN_FALSE;
1420 }
1421 Py_RETURN_TRUE;
1422 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 it = PyObject_GetIter(other);
1425 if (it == NULL)
1426 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001429 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if (hash == -1) {
1432 Py_DECREF(key);
1433 Py_DECREF(it);
1434 return NULL;
1435 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001436 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001438 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 Py_DECREF(it);
1440 return NULL;
1441 }
1442 if (rv) {
1443 Py_DECREF(it);
1444 Py_RETURN_FALSE;
1445 }
1446 }
1447 Py_DECREF(it);
1448 if (PyErr_Occurred())
1449 return NULL;
1450 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001451}
1452
1453PyDoc_STRVAR(isdisjoint_doc,
1454"Return True if two sets have a null intersection.");
1455
Neal Norwitz6576bd82005-11-13 18:41:28 +00001456static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001457set_difference_update_internal(PySetObject *so, PyObject *other)
1458{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001459 if (PySet_GET_SIZE(so) == 0) {
1460 return 0;
1461 }
1462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 if ((PyObject *)so == other)
1464 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 if (PyAnySet_Check(other)) {
1467 setentry *entry;
1468 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001471 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 return -1;
1473 } else {
1474 PyObject *key, *it;
1475 it = PyObject_GetIter(other);
1476 if (it == NULL)
1477 return -1;
1478
1479 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001480 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 Py_DECREF(it);
1482 Py_DECREF(key);
1483 return -1;
1484 }
1485 Py_DECREF(key);
1486 }
1487 Py_DECREF(it);
1488 if (PyErr_Occurred())
1489 return -1;
1490 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001491 /* If more than 1/4th are dummies, then resize them away. */
1492 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001494 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001495}
1496
Raymond Hettingera690a992003-11-16 16:17:49 +00001497static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001498set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001499{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1503 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001504 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 return NULL;
1506 }
1507 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001508}
1509
1510PyDoc_STRVAR(difference_update_doc,
1511"Remove all elements of another set from this set.");
1512
1513static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001514set_copy_and_difference(PySetObject *so, PyObject *other)
1515{
1516 PyObject *result;
1517
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301518 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001519 if (result == NULL)
1520 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001521 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001522 return result;
1523 Py_DECREF(result);
1524 return NULL;
1525}
1526
1527static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001528set_difference(PySetObject *so, PyObject *other)
1529{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001531 PyObject *key;
1532 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001534 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001535 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001536
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001537 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301538 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001539 }
1540
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001541 if (PyAnySet_Check(other)) {
1542 other_size = PySet_GET_SIZE(other);
1543 }
1544 else if (PyDict_CheckExact(other)) {
1545 other_size = PyDict_GET_SIZE(other);
1546 }
1547 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001548 return set_copy_and_difference(so, other);
1549 }
1550
1551 /* If len(so) much more than len(other), it's more efficient to simply copy
1552 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001553 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001554 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 result = make_new_set_basetype(Py_TYPE(so), NULL);
1558 if (result == NULL)
1559 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 if (PyDict_CheckExact(other)) {
1562 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001563 key = entry->key;
1564 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001565 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001566 if (rv < 0) {
1567 Py_DECREF(result);
1568 return NULL;
1569 }
1570 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001571 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 Py_DECREF(result);
1573 return NULL;
1574 }
1575 }
1576 }
1577 return result;
1578 }
1579
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001580 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001582 key = entry->key;
1583 hash = entry->hash;
1584 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001585 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001586 Py_DECREF(result);
1587 return NULL;
1588 }
1589 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001590 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 }
1595 }
1596 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001597}
1598
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001599static PyObject *
1600set_difference_multi(PySetObject *so, PyObject *args)
1601{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001602 Py_ssize_t i;
1603 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001604
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301606 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001607
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 other = PyTuple_GET_ITEM(args, 0);
1609 result = set_difference(so, other);
1610 if (result == NULL)
1611 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001612
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1614 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001615 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 Py_DECREF(result);
1617 return NULL;
1618 }
1619 }
1620 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001621}
1622
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001623PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001624"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001625\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001627static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001628set_sub(PySetObject *so, PyObject *other)
1629{
Brian Curtindfc80e32011-08-10 20:28:54 -05001630 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1631 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001633}
1634
1635static PyObject *
1636set_isub(PySetObject *so, PyObject *other)
1637{
Brian Curtindfc80e32011-08-10 20:28:54 -05001638 if (!PyAnySet_Check(other))
1639 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001640 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 return NULL;
1642 Py_INCREF(so);
1643 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001644}
1645
1646static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001647set_symmetric_difference_update(PySetObject *so, PyObject *other)
1648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001649 PySetObject *otherset;
1650 PyObject *key;
1651 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001652 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001653 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001654 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301657 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 if (PyDict_CheckExact(other)) {
1660 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001661 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001662 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001663 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001664 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001665 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001668 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001669 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001670 Py_DECREF(key);
1671 return NULL;
1672 }
1673 }
Georg Brandl2d444492010-09-03 10:52:55 +00001674 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 }
1676 Py_RETURN_NONE;
1677 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 if (PyAnySet_Check(other)) {
1680 Py_INCREF(other);
1681 otherset = (PySetObject *)other;
1682 } else {
1683 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1684 if (otherset == NULL)
1685 return NULL;
1686 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001689 key = entry->key;
1690 hash = entry->hash;
1691 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001692 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001693 Py_DECREF(otherset);
1694 return NULL;
1695 }
1696 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001697 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 Py_DECREF(otherset);
1699 return NULL;
1700 }
1701 }
1702 }
1703 Py_DECREF(otherset);
1704 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001705}
1706
1707PyDoc_STRVAR(symmetric_difference_update_doc,
1708"Update a set with the symmetric difference of itself and another.");
1709
1710static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001711set_symmetric_difference(PySetObject *so, PyObject *other)
1712{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001713 PyObject *rv;
1714 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001715
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001716 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1717 if (otherset == NULL)
1718 return NULL;
1719 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001720 if (rv == NULL) {
1721 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001723 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 Py_DECREF(rv);
1725 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001726}
1727
1728PyDoc_STRVAR(symmetric_difference_doc,
1729"Return the symmetric difference of two sets as a new set.\n\
1730\n\
1731(i.e. all elements that are in exactly one of the sets.)");
1732
1733static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001734set_xor(PySetObject *so, PyObject *other)
1735{
Brian Curtindfc80e32011-08-10 20:28:54 -05001736 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1737 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001739}
1740
1741static PyObject *
1742set_ixor(PySetObject *so, PyObject *other)
1743{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001745
Brian Curtindfc80e32011-08-10 20:28:54 -05001746 if (!PyAnySet_Check(other))
1747 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 result = set_symmetric_difference_update(so, other);
1749 if (result == NULL)
1750 return NULL;
1751 Py_DECREF(result);
1752 Py_INCREF(so);
1753 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001754}
1755
1756static PyObject *
1757set_issubset(PySetObject *so, PyObject *other)
1758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001759 setentry *entry;
1760 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001761 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 if (!PyAnySet_Check(other)) {
1764 PyObject *tmp, *result;
1765 tmp = make_new_set(&PySet_Type, other);
1766 if (tmp == NULL)
1767 return NULL;
1768 result = set_issubset(so, tmp);
1769 Py_DECREF(tmp);
1770 return result;
1771 }
1772 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1773 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001775 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001776 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001777 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 return NULL;
1779 if (!rv)
1780 Py_RETURN_FALSE;
1781 }
1782 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001783}
1784
1785PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1786
1787static PyObject *
1788set_issuperset(PySetObject *so, PyObject *other)
1789{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001790 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001791
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001792 if (!PyAnySet_Check(other)) {
1793 tmp = make_new_set(&PySet_Type, other);
1794 if (tmp == NULL)
1795 return NULL;
1796 result = set_issuperset(so, tmp);
1797 Py_DECREF(tmp);
1798 return result;
1799 }
1800 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001801}
1802
1803PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1804
Raymond Hettingera690a992003-11-16 16:17:49 +00001805static PyObject *
1806set_richcompare(PySetObject *v, PyObject *w, int op)
1807{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001808 PyObject *r1;
1809 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001810
Brian Curtindfc80e32011-08-10 20:28:54 -05001811 if(!PyAnySet_Check(w))
1812 Py_RETURN_NOTIMPLEMENTED;
1813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 switch (op) {
1815 case Py_EQ:
1816 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1817 Py_RETURN_FALSE;
1818 if (v->hash != -1 &&
1819 ((PySetObject *)w)->hash != -1 &&
1820 v->hash != ((PySetObject *)w)->hash)
1821 Py_RETURN_FALSE;
1822 return set_issubset(v, w);
1823 case Py_NE:
1824 r1 = set_richcompare(v, w, Py_EQ);
1825 if (r1 == NULL)
1826 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001827 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001829 if (r2 < 0)
1830 return NULL;
1831 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 case Py_LE:
1833 return set_issubset(v, w);
1834 case Py_GE:
1835 return set_issuperset(v, w);
1836 case Py_LT:
1837 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1838 Py_RETURN_FALSE;
1839 return set_issubset(v, w);
1840 case Py_GT:
1841 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1842 Py_RETURN_FALSE;
1843 return set_issuperset(v, w);
1844 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001845 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001846}
1847
Raymond Hettingera690a992003-11-16 16:17:49 +00001848static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001849set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001850{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001851 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 return NULL;
1853 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001854}
1855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001857"Add an element to a set.\n\
1858\n\
1859This has no effect if the element is already present.");
1860
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001861static int
1862set_contains(PySetObject *so, PyObject *key)
1863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 PyObject *tmpkey;
1865 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001868 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1870 return -1;
1871 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001872 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 if (tmpkey == NULL)
1874 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001875 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001876 Py_DECREF(tmpkey);
1877 }
1878 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001879}
1880
1881static PyObject *
1882set_direct_contains(PySetObject *so, PyObject *key)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001887 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 return NULL;
1889 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001890}
1891
1892PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1893
Raymond Hettingera690a992003-11-16 16:17:49 +00001894static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001895set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001896{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001897 PyObject *tmpkey;
1898 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001901 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1903 return NULL;
1904 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001905 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 if (tmpkey == NULL)
1907 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001909 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001910 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 return NULL;
1912 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001913
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001915 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 return NULL;
1917 }
1918 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001919}
1920
1921PyDoc_STRVAR(remove_doc,
1922"Remove an element from a set; it must be a member.\n\
1923\n\
1924If the element is not a member, raise a KeyError.");
1925
1926static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001927set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001928{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001929 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001933 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1935 return NULL;
1936 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001937 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (tmpkey == NULL)
1939 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001940 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001942 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001943 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 }
1945 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001946}
1947
1948PyDoc_STRVAR(discard_doc,
1949"Remove an element from a set if it is a member.\n\
1950\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001952
1953static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301954set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001955{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001957 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 keys = PySequence_List((PyObject *)so);
1960 if (keys == NULL)
1961 goto done;
1962 args = PyTuple_Pack(1, keys);
1963 if (args == NULL)
1964 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001965 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 if (dict == NULL) {
1967 PyErr_Clear();
1968 dict = Py_None;
1969 Py_INCREF(dict);
1970 }
1971 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001972done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 Py_XDECREF(args);
1974 Py_XDECREF(keys);
1975 Py_XDECREF(dict);
1976 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001977}
1978
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001979static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301980set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001983
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001984 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 if (so->table != so->smalltable)
1986 res = res + (so->mask + 1) * sizeof(setentry);
1987 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001988}
1989
1990PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001991static int
1992set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001994 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001995
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001996 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 return -1;
1998 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1999 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002000 if (self->fill)
2001 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 self->hash = -1;
2003 if (iterable == NULL)
2004 return 0;
2005 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002006}
2007
Raymond Hettingera690a992003-11-16 16:17:49 +00002008static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 set_len, /* sq_length */
2010 0, /* sq_concat */
2011 0, /* sq_repeat */
2012 0, /* sq_item */
2013 0, /* sq_slice */
2014 0, /* sq_ass_item */
2015 0, /* sq_ass_slice */
2016 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002017};
2018
2019/* set object ********************************************************/
2020
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002021#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302022static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002023
2024PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2025All is well if assertions don't fail.");
2026#endif
2027
Raymond Hettingera690a992003-11-16 16:17:49 +00002028static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 {"add", (PyCFunction)set_add, METH_O,
2030 add_doc},
2031 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2032 clear_doc},
2033 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2034 contains_doc},
2035 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2036 copy_doc},
2037 {"discard", (PyCFunction)set_discard, METH_O,
2038 discard_doc},
2039 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2040 difference_doc},
2041 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2042 difference_update_doc},
2043 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2044 intersection_doc},
2045 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2046 intersection_update_doc},
2047 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2048 isdisjoint_doc},
2049 {"issubset", (PyCFunction)set_issubset, METH_O,
2050 issubset_doc},
2051 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2052 issuperset_doc},
2053 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2054 pop_doc},
2055 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2056 reduce_doc},
2057 {"remove", (PyCFunction)set_remove, METH_O,
2058 remove_doc},
2059 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2060 sizeof_doc},
2061 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2062 symmetric_difference_doc},
2063 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2064 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002065#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2067 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002068#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 {"union", (PyCFunction)set_union, METH_VARARGS,
2070 union_doc},
2071 {"update", (PyCFunction)set_update, METH_VARARGS,
2072 update_doc},
2073 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002074};
2075
2076static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 0, /*nb_add*/
2078 (binaryfunc)set_sub, /*nb_subtract*/
2079 0, /*nb_multiply*/
2080 0, /*nb_remainder*/
2081 0, /*nb_divmod*/
2082 0, /*nb_power*/
2083 0, /*nb_negative*/
2084 0, /*nb_positive*/
2085 0, /*nb_absolute*/
2086 0, /*nb_bool*/
2087 0, /*nb_invert*/
2088 0, /*nb_lshift*/
2089 0, /*nb_rshift*/
2090 (binaryfunc)set_and, /*nb_and*/
2091 (binaryfunc)set_xor, /*nb_xor*/
2092 (binaryfunc)set_or, /*nb_or*/
2093 0, /*nb_int*/
2094 0, /*nb_reserved*/
2095 0, /*nb_float*/
2096 0, /*nb_inplace_add*/
2097 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2098 0, /*nb_inplace_multiply*/
2099 0, /*nb_inplace_remainder*/
2100 0, /*nb_inplace_power*/
2101 0, /*nb_inplace_lshift*/
2102 0, /*nb_inplace_rshift*/
2103 (binaryfunc)set_iand, /*nb_inplace_and*/
2104 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2105 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002106};
2107
2108PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002109"set() -> new empty set object\n\
2110set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002111\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002112Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002113
2114PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2116 "set", /* tp_name */
2117 sizeof(PySetObject), /* tp_basicsize */
2118 0, /* tp_itemsize */
2119 /* methods */
2120 (destructor)set_dealloc, /* tp_dealloc */
2121 0, /* tp_print */
2122 0, /* tp_getattr */
2123 0, /* tp_setattr */
2124 0, /* tp_reserved */
2125 (reprfunc)set_repr, /* tp_repr */
2126 &set_as_number, /* tp_as_number */
2127 &set_as_sequence, /* tp_as_sequence */
2128 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002129 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002130 0, /* tp_call */
2131 0, /* tp_str */
2132 PyObject_GenericGetAttr, /* tp_getattro */
2133 0, /* tp_setattro */
2134 0, /* tp_as_buffer */
2135 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2136 Py_TPFLAGS_BASETYPE, /* tp_flags */
2137 set_doc, /* tp_doc */
2138 (traverseproc)set_traverse, /* tp_traverse */
2139 (inquiry)set_clear_internal, /* tp_clear */
2140 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002141 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2142 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002143 0, /* tp_iternext */
2144 set_methods, /* tp_methods */
2145 0, /* tp_members */
2146 0, /* tp_getset */
2147 0, /* tp_base */
2148 0, /* tp_dict */
2149 0, /* tp_descr_get */
2150 0, /* tp_descr_set */
2151 0, /* tp_dictoffset */
2152 (initproc)set_init, /* tp_init */
2153 PyType_GenericAlloc, /* tp_alloc */
2154 set_new, /* tp_new */
2155 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002156};
2157
2158/* frozenset object ********************************************************/
2159
2160
2161static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2163 contains_doc},
2164 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2165 copy_doc},
2166 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2167 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002168 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 intersection_doc},
2170 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2171 isdisjoint_doc},
2172 {"issubset", (PyCFunction)set_issubset, METH_O,
2173 issubset_doc},
2174 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2175 issuperset_doc},
2176 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2177 reduce_doc},
2178 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2179 sizeof_doc},
2180 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2181 symmetric_difference_doc},
2182 {"union", (PyCFunction)set_union, METH_VARARGS,
2183 union_doc},
2184 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002185};
2186
2187static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 0, /*nb_add*/
2189 (binaryfunc)set_sub, /*nb_subtract*/
2190 0, /*nb_multiply*/
2191 0, /*nb_remainder*/
2192 0, /*nb_divmod*/
2193 0, /*nb_power*/
2194 0, /*nb_negative*/
2195 0, /*nb_positive*/
2196 0, /*nb_absolute*/
2197 0, /*nb_bool*/
2198 0, /*nb_invert*/
2199 0, /*nb_lshift*/
2200 0, /*nb_rshift*/
2201 (binaryfunc)set_and, /*nb_and*/
2202 (binaryfunc)set_xor, /*nb_xor*/
2203 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002204};
2205
2206PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002207"frozenset() -> empty frozenset object\n\
2208frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002209\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002210Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002211
2212PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002213 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2214 "frozenset", /* tp_name */
2215 sizeof(PySetObject), /* tp_basicsize */
2216 0, /* tp_itemsize */
2217 /* methods */
2218 (destructor)set_dealloc, /* tp_dealloc */
2219 0, /* tp_print */
2220 0, /* tp_getattr */
2221 0, /* tp_setattr */
2222 0, /* tp_reserved */
2223 (reprfunc)set_repr, /* tp_repr */
2224 &frozenset_as_number, /* tp_as_number */
2225 &set_as_sequence, /* tp_as_sequence */
2226 0, /* tp_as_mapping */
2227 frozenset_hash, /* tp_hash */
2228 0, /* tp_call */
2229 0, /* tp_str */
2230 PyObject_GenericGetAttr, /* tp_getattro */
2231 0, /* tp_setattro */
2232 0, /* tp_as_buffer */
2233 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2234 Py_TPFLAGS_BASETYPE, /* tp_flags */
2235 frozenset_doc, /* tp_doc */
2236 (traverseproc)set_traverse, /* tp_traverse */
2237 (inquiry)set_clear_internal, /* tp_clear */
2238 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002239 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002240 (getiterfunc)set_iter, /* tp_iter */
2241 0, /* tp_iternext */
2242 frozenset_methods, /* tp_methods */
2243 0, /* tp_members */
2244 0, /* tp_getset */
2245 0, /* tp_base */
2246 0, /* tp_dict */
2247 0, /* tp_descr_get */
2248 0, /* tp_descr_set */
2249 0, /* tp_dictoffset */
2250 0, /* tp_init */
2251 PyType_GenericAlloc, /* tp_alloc */
2252 frozenset_new, /* tp_new */
2253 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002254};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002255
2256
2257/***** C API functions *************************************************/
2258
2259PyObject *
2260PySet_New(PyObject *iterable)
2261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002263}
2264
2265PyObject *
2266PyFrozenSet_New(PyObject *iterable)
2267{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002268 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002269}
2270
Neal Norwitz8c49c822006-03-04 18:41:19 +00002271Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002272PySet_Size(PyObject *anyset)
2273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002274 if (!PyAnySet_Check(anyset)) {
2275 PyErr_BadInternalCall();
2276 return -1;
2277 }
2278 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002279}
2280
2281int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002282PySet_Clear(PyObject *set)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 if (!PySet_Check(set)) {
2285 PyErr_BadInternalCall();
2286 return -1;
2287 }
2288 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002289}
2290
2291int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002292PySet_Contains(PyObject *anyset, PyObject *key)
2293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002294 if (!PyAnySet_Check(anyset)) {
2295 PyErr_BadInternalCall();
2296 return -1;
2297 }
2298 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002299}
2300
2301int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002302PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002304 if (!PySet_Check(set)) {
2305 PyErr_BadInternalCall();
2306 return -1;
2307 }
2308 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002309}
2310
2311int
Christian Heimesfd66e512008-01-29 12:18:50 +00002312PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PySet_Check(anyset) &&
2315 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2316 PyErr_BadInternalCall();
2317 return -1;
2318 }
2319 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002320}
2321
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002322int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002323PySet_ClearFreeList(void)
2324{
2325 return 0;
2326}
2327
2328void
2329PySet_Fini(void)
2330{
2331 Py_CLEAR(emptyfrozenset);
2332}
2333
2334int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002335_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 if (!PyAnySet_Check(set)) {
2340 PyErr_BadInternalCall();
2341 return -1;
2342 }
2343 if (set_next((PySetObject *)set, pos, &entry) == 0)
2344 return 0;
2345 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002346 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002348}
2349
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002350PyObject *
2351PySet_Pop(PyObject *set)
2352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 if (!PySet_Check(set)) {
2354 PyErr_BadInternalCall();
2355 return NULL;
2356 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302357 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002358}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002359
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002360int
2361_PySet_Update(PyObject *set, PyObject *iterable)
2362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 if (!PySet_Check(set)) {
2364 PyErr_BadInternalCall();
2365 return -1;
2366 }
2367 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002368}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002369
Raymond Hettingere259f132013-12-15 11:56:14 -08002370/* Exported for the gdb plugin's benefit. */
2371PyObject *_PySet_Dummy = dummy;
2372
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002373#ifdef Py_DEBUG
2374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376 Returns True and original set is restored. */
2377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378#define assertRaises(call_return_value, exception) \
2379 do { \
2380 assert(call_return_value); \
2381 assert(PyErr_ExceptionMatches(exception)); \
2382 PyErr_Clear(); \
2383 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002384
2385static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302386test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002389 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002391 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002393 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 /* Verify preconditions */
2397 assert(PyAnySet_Check(ob));
2398 assert(PyAnySet_CheckExact(ob));
2399 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002401 /* so.clear(); so |= set("abc"); */
2402 str = PyUnicode_FromString("abc");
2403 if (str == NULL)
2404 return NULL;
2405 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002406 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 Py_DECREF(str);
2408 return NULL;
2409 }
2410 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* Exercise type/size checks */
2413 assert(PySet_Size(ob) == 3);
2414 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 /* Raise TypeError for non-iterable constructor arguments */
2417 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2418 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002420 /* Raise TypeError for unhashable key */
2421 dup = PySet_New(ob);
2422 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2423 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2424 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 /* Exercise successful pop, contains, add, and discard */
2427 elem = PySet_Pop(ob);
2428 assert(PySet_Contains(ob, elem) == 0);
2429 assert(PySet_GET_SIZE(ob) == 2);
2430 assert(PySet_Add(ob, elem) == 0);
2431 assert(PySet_Contains(ob, elem) == 1);
2432 assert(PySet_GET_SIZE(ob) == 3);
2433 assert(PySet_Discard(ob, elem) == 1);
2434 assert(PySet_GET_SIZE(ob) == 2);
2435 assert(PySet_Discard(ob, elem) == 0);
2436 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 /* Exercise clear */
2439 dup2 = PySet_New(dup);
2440 assert(PySet_Clear(dup2) == 0);
2441 assert(PySet_Size(dup2) == 0);
2442 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002443
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002444 /* Raise SystemError on clear or update of frozen set */
2445 f = PyFrozenSet_New(dup);
2446 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2447 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2448 assert(PySet_Add(f, elem) == 0);
2449 Py_INCREF(f);
2450 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2451 Py_DECREF(f);
2452 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002454 /* Exercise direct iteration */
2455 i = 0, count = 0;
2456 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002457 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002458 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2459 count++;
2460 }
2461 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002463 /* Exercise updates */
2464 dup2 = PySet_New(NULL);
2465 assert(_PySet_Update(dup2, dup) == 0);
2466 assert(PySet_Size(dup2) == 3);
2467 assert(_PySet_Update(dup2, dup) == 0);
2468 assert(PySet_Size(dup2) == 3);
2469 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002470
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002471 /* Raise SystemError when self argument is not a set or frozenset. */
2472 t = PyTuple_New(0);
2473 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2474 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2475 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002477 /* Raise SystemError when self argument is not a set. */
2478 f = PyFrozenSet_New(dup);
2479 assert(PySet_Size(f) == 3);
2480 assert(PyFrozenSet_CheckExact(f));
2481 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2482 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2483 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Raise KeyError when popping from an empty set */
2486 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2487 Py_DECREF(ob);
2488 assert(PySet_GET_SIZE(ob) == 0);
2489 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002490
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002491 /* Restore the set from the copy using the PyNumber API */
2492 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2493 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002495 /* Verify constructors accept NULL arguments */
2496 f = PySet_New(NULL);
2497 assert(f != NULL);
2498 assert(PySet_GET_SIZE(f) == 0);
2499 Py_DECREF(f);
2500 f = PyFrozenSet_New(NULL);
2501 assert(f != NULL);
2502 assert(PyFrozenSet_CheckExact(f));
2503 assert(PySet_GET_SIZE(f) == 0);
2504 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 Py_DECREF(elem);
2507 Py_DECREF(dup);
2508 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002509}
2510
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002511#undef assertRaises
2512
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002513#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002514
2515/***** Dummy Struct *************************************************/
2516
2517static PyObject *
2518dummy_repr(PyObject *op)
2519{
2520 return PyUnicode_FromString("<dummy key>");
2521}
2522
2523static void
2524dummy_dealloc(PyObject* ignore)
2525{
2526 Py_FatalError("deallocating <dummy key>");
2527}
2528
2529static PyTypeObject _PySetDummy_Type = {
2530 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2531 "<dummy key> type",
2532 0,
2533 0,
2534 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2535 0, /*tp_print*/
2536 0, /*tp_getattr*/
2537 0, /*tp_setattr*/
2538 0, /*tp_reserved*/
2539 dummy_repr, /*tp_repr*/
2540 0, /*tp_as_number*/
2541 0, /*tp_as_sequence*/
2542 0, /*tp_as_mapping*/
2543 0, /*tp_hash */
2544 0, /*tp_call */
2545 0, /*tp_str */
2546 0, /*tp_getattro */
2547 0, /*tp_setattro */
2548 0, /*tp_as_buffer */
2549 Py_TPFLAGS_DEFAULT, /*tp_flags */
2550};
2551
2552static PyObject _dummy_struct = {
2553 _PyObject_EXTRA_INIT
2554 2, &_PySetDummy_Type
2555};
2556