blob: e7a528888ef0ec0819069e94269d9c32d825a825 [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{
846 PyObject *list;
847 setiterobject tmp;
848
849 list = PyList_New(0);
850 if (!list)
851 return NULL;
852
Ezio Melotti0e1af282012-09-28 16:43:40 +0300853 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000854 tmp = *si;
855 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300856
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000857 /* iterate the temporary into a list */
858 for(;;) {
859 PyObject *element = setiter_iternext(&tmp);
860 if (element) {
861 if (PyList_Append(list, element)) {
862 Py_DECREF(element);
863 Py_DECREF(list);
864 Py_XDECREF(tmp.si_set);
865 return NULL;
866 }
867 Py_DECREF(element);
868 } else
869 break;
870 }
871 Py_XDECREF(tmp.si_set);
872 /* check for error */
873 if (tmp.si_set != NULL) {
874 /* we have an error */
875 Py_DECREF(list);
876 return NULL;
877 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200878 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000879}
880
881PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
882
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000883static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000885 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000887};
888
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000889static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000890{
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700891 PyObject *key;
892 Py_ssize_t i, mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200893 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 if (so == NULL)
897 return NULL;
898 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 if (si->si_used != so->used) {
901 PyErr_SetString(PyExc_RuntimeError,
902 "Set changed size during iteration");
903 si->si_used = -1; /* Make this state sticky */
904 return NULL;
905 }
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700906
907 i = si->si_pos;
908 assert(i>=0);
909 entry = so->table;
910 mask = so->mask;
911 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
912 i++;
913 si->si_pos = i+1;
914 if (i > mask)
915 goto fail;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 si->len--;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700917 key = entry[i].key;
918 Py_INCREF(key);
919 return key;
920
921fail:
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700922 si->si_set = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +0300923 Py_DECREF(so);
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700924 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000925}
926
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000927PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 PyVarObject_HEAD_INIT(&PyType_Type, 0)
929 "set_iterator", /* tp_name */
930 sizeof(setiterobject), /* tp_basicsize */
931 0, /* tp_itemsize */
932 /* methods */
933 (destructor)setiter_dealloc, /* tp_dealloc */
934 0, /* tp_print */
935 0, /* tp_getattr */
936 0, /* tp_setattr */
937 0, /* tp_reserved */
938 0, /* tp_repr */
939 0, /* tp_as_number */
940 0, /* tp_as_sequence */
941 0, /* tp_as_mapping */
942 0, /* tp_hash */
943 0, /* tp_call */
944 0, /* tp_str */
945 PyObject_GenericGetAttr, /* tp_getattro */
946 0, /* tp_setattro */
947 0, /* tp_as_buffer */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -0700948 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 0, /* tp_doc */
950 (traverseproc)setiter_traverse, /* tp_traverse */
951 0, /* tp_clear */
952 0, /* tp_richcompare */
953 0, /* tp_weaklistoffset */
954 PyObject_SelfIter, /* tp_iter */
955 (iternextfunc)setiter_iternext, /* tp_iternext */
956 setiter_methods, /* tp_methods */
957 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000958};
959
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000960static PyObject *
961set_iter(PySetObject *so)
962{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
964 if (si == NULL)
965 return NULL;
966 Py_INCREF(so);
967 si->si_set = so;
968 si->si_used = so->used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700969 si->si_pos = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 si->len = so->used;
971 _PyObject_GC_TRACK(si);
972 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000973}
974
Raymond Hettingerd7946662005-08-01 21:39:29 +0000975static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000976set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 if (PyAnySet_Check(other))
981 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 if (PyDict_CheckExact(other)) {
984 PyObject *value;
985 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000986 Py_hash_t hash;
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +0200987 Py_ssize_t dictsize = PyDict_GET_SIZE(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 /* Do one big resize at the start, rather than
990 * incrementally resizing as we insert new keys. Expect
991 * that there will be no (or few) overlapping keys.
992 */
Raymond Hettingerc2480dc2015-07-04 08:46:31 -0700993 if (dictsize < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 return -1;
Raymond Hettinger5cd87a82017-02-04 02:43:42 -0800995 if ((so->fill + dictsize)*5 >= so->mask*3) {
INADA Naokie82cf862017-04-01 17:20:25 +0900996 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000997 return -1;
998 }
999 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001000 if (set_add_entry(so, key, hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 return -1;
1002 }
1003 return 0;
1004 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 it = PyObject_GetIter(other);
1007 if (it == NULL)
1008 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +00001009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001011 if (set_add_key(so, key)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 Py_DECREF(it);
1013 Py_DECREF(key);
1014 return -1;
1015 }
1016 Py_DECREF(key);
1017 }
1018 Py_DECREF(it);
1019 if (PyErr_Occurred())
1020 return -1;
1021 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001022}
1023
1024static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001025set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001026{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001028
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1030 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001031 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 return NULL;
1033 }
1034 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001035}
1036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001038"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +00001039
Raymond Hettinger426d9952014-05-18 21:40:20 +01001040/* XXX Todo:
1041 If aligned memory allocations become available, make the
1042 set object 64 byte aligned so that most of the fields
1043 can be retrieved or updated in a single cache line.
1044*/
1045
Raymond Hettingera38123e2003-11-24 22:18:49 +00001046static PyObject *
1047make_new_set(PyTypeObject *type, PyObject *iterable)
1048{
Raymond Hettinger8421d712016-04-29 01:37:05 -07001049 PySetObject *so;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001050
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001051 so = (PySetObject *)type->tp_alloc(type, 0);
1052 if (so == NULL)
1053 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001054
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001055 so->fill = 0;
1056 so->used = 0;
1057 so->mask = PySet_MINSIZE - 1;
1058 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001059 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001060 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001064 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 Py_DECREF(so);
1066 return NULL;
1067 }
1068 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001071}
1072
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001073static PyObject *
1074make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1077 if (PyType_IsSubtype(type, &PySet_Type))
1078 type = &PySet_Type;
1079 else
1080 type = &PyFrozenSet_Type;
1081 }
1082 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001083}
1084
Raymond Hettingerd7946662005-08-01 21:39:29 +00001085/* The empty frozenset is a singleton */
1086static PyObject *emptyfrozenset = NULL;
1087
Raymond Hettingera690a992003-11-16 16:17:49 +00001088static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001089frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001092
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03001093 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1097 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 if (type != &PyFrozenSet_Type)
1100 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001101
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 if (iterable != NULL) {
1103 /* frozenset(f) is idempotent */
1104 if (PyFrozenSet_CheckExact(iterable)) {
1105 Py_INCREF(iterable);
1106 return iterable;
1107 }
1108 result = make_new_set(type, iterable);
1109 if (result == NULL || PySet_GET_SIZE(result))
1110 return result;
1111 Py_DECREF(result);
1112 }
1113 /* The empty frozenset is a singleton */
1114 if (emptyfrozenset == NULL)
1115 emptyfrozenset = make_new_set(type, NULL);
1116 Py_XINCREF(emptyfrozenset);
1117 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001118}
1119
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001120static PyObject *
1121set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001124}
1125
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001126/* set_swap_bodies() switches the contents of any two sets by moving their
1127 internal data pointers and, if needed, copying the internal smalltables.
1128 Semantically equivalent to:
1129
1130 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1131
1132 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001133 Useful for operations that update in-place (by allowing an intermediate
1134 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001135*/
1136
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001137static void
1138set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 Py_ssize_t t;
1141 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001143 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001144
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 t = a->fill; a->fill = b->fill; b->fill = t;
1146 t = a->used; a->used = b->used; b->used = t;
1147 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 u = a->table;
1150 if (a->table == a->smalltable)
1151 u = b->smalltable;
1152 a->table = b->table;
1153 if (b->table == b->smalltable)
1154 a->table = a->smalltable;
1155 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001156
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 if (a->table == a->smalltable || b->table == b->smalltable) {
1158 memcpy(tab, a->smalltable, sizeof(tab));
1159 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1160 memcpy(b->smalltable, tab, sizeof(tab));
1161 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1164 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1165 h = a->hash; a->hash = b->hash; b->hash = h;
1166 } else {
1167 a->hash = -1;
1168 b->hash = -1;
1169 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001170}
1171
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001172static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301173set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001176}
1177
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001178static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301179frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 if (PyFrozenSet_CheckExact(so)) {
1182 Py_INCREF(so);
1183 return (PyObject *)so;
1184 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301185 return set_copy(so, NULL);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001186}
1187
Raymond Hettingera690a992003-11-16 16:17:49 +00001188PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1189
1190static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301191set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc991db22005-08-11 07:58:45 +00001192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 set_clear_internal(so);
1194 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001195}
1196
1197PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1198
1199static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001200set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 PySetObject *result;
1203 PyObject *other;
1204 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001205
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301206 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 if (result == NULL)
1208 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1211 other = PyTuple_GET_ITEM(args, i);
1212 if ((PyObject *)so == other)
1213 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001214 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 Py_DECREF(result);
1216 return NULL;
1217 }
1218 }
1219 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001220}
1221
1222PyDoc_STRVAR(union_doc,
1223 "Return the union of sets as a new set.\n\
1224\n\
1225(i.e. all elements that are in either set.)");
1226
1227static PyObject *
1228set_or(PySetObject *so, PyObject *other)
1229{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001231
Brian Curtindfc80e32011-08-10 20:28:54 -05001232 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1233 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001234
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301235 result = (PySetObject *)set_copy(so, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 if (result == NULL)
1237 return NULL;
1238 if ((PyObject *)so == other)
1239 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001240 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 Py_DECREF(result);
1242 return NULL;
1243 }
1244 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001245}
1246
Raymond Hettingera690a992003-11-16 16:17:49 +00001247static PyObject *
1248set_ior(PySetObject *so, PyObject *other)
1249{
Brian Curtindfc80e32011-08-10 20:28:54 -05001250 if (!PyAnySet_Check(other))
1251 Py_RETURN_NOTIMPLEMENTED;
1252
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001253 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 return NULL;
1255 Py_INCREF(so);
1256 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001257}
1258
1259static PyObject *
1260set_intersection(PySetObject *so, PyObject *other)
1261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 PySetObject *result;
1263 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001264 Py_hash_t hash;
1265 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301268 return set_copy(so, NULL);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001269
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1271 if (result == NULL)
1272 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if (PyAnySet_Check(other)) {
1275 Py_ssize_t pos = 0;
1276 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1279 tmp = (PyObject *)so;
1280 so = (PySetObject *)other;
1281 other = tmp;
1282 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001283
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001285 key = entry->key;
1286 hash = entry->hash;
1287 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001288 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 Py_DECREF(result);
1290 return NULL;
1291 }
1292 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001293 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 Py_DECREF(result);
1295 return NULL;
1296 }
1297 }
1298 }
1299 return (PyObject *)result;
1300 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 it = PyObject_GetIter(other);
1303 if (it == NULL) {
1304 Py_DECREF(result);
1305 return NULL;
1306 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001307
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001309 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001310 if (hash == -1)
1311 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001312 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001313 if (rv < 0)
1314 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001316 if (set_add_entry(result, key, hash))
1317 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 }
1319 Py_DECREF(key);
1320 }
1321 Py_DECREF(it);
1322 if (PyErr_Occurred()) {
1323 Py_DECREF(result);
1324 return NULL;
1325 }
1326 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001327 error:
1328 Py_DECREF(it);
1329 Py_DECREF(result);
1330 Py_DECREF(key);
1331 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001332}
1333
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001334static PyObject *
1335set_intersection_multi(PySetObject *so, PyObject *args)
1336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_ssize_t i;
1338 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301341 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 Py_INCREF(so);
1344 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1345 PyObject *other = PyTuple_GET_ITEM(args, i);
1346 PyObject *newresult = set_intersection((PySetObject *)result, other);
1347 if (newresult == NULL) {
1348 Py_DECREF(result);
1349 return NULL;
1350 }
1351 Py_DECREF(result);
1352 result = newresult;
1353 }
1354 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001355}
1356
Raymond Hettingera690a992003-11-16 16:17:49 +00001357PyDoc_STRVAR(intersection_doc,
1358"Return the intersection of two sets as a new set.\n\
1359\n\
1360(i.e. all elements that are in both sets.)");
1361
1362static PyObject *
1363set_intersection_update(PySetObject *so, PyObject *other)
1364{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 tmp = set_intersection(so, other);
1368 if (tmp == NULL)
1369 return NULL;
1370 set_swap_bodies(so, (PySetObject *)tmp);
1371 Py_DECREF(tmp);
1372 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001373}
1374
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001375static PyObject *
1376set_intersection_update_multi(PySetObject *so, PyObject *args)
1377{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 tmp = set_intersection_multi(so, args);
1381 if (tmp == NULL)
1382 return NULL;
1383 set_swap_bodies(so, (PySetObject *)tmp);
1384 Py_DECREF(tmp);
1385 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001386}
1387
Raymond Hettingera690a992003-11-16 16:17:49 +00001388PyDoc_STRVAR(intersection_update_doc,
1389"Update a set with the intersection of itself and another.");
1390
1391static PyObject *
1392set_and(PySetObject *so, PyObject *other)
1393{
Brian Curtindfc80e32011-08-10 20:28:54 -05001394 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1395 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001397}
1398
1399static PyObject *
1400set_iand(PySetObject *so, PyObject *other)
1401{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001403
Brian Curtindfc80e32011-08-10 20:28:54 -05001404 if (!PyAnySet_Check(other))
1405 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 result = set_intersection_update(so, other);
1407 if (result == NULL)
1408 return NULL;
1409 Py_DECREF(result);
1410 Py_INCREF(so);
1411 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001412}
1413
Guido van Rossum58da9312007-11-10 23:39:45 +00001414static PyObject *
1415set_isdisjoint(PySetObject *so, PyObject *other)
1416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001418 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001419
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if ((PyObject *)so == other) {
1421 if (PySet_GET_SIZE(so) == 0)
1422 Py_RETURN_TRUE;
1423 else
1424 Py_RETURN_FALSE;
1425 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (PyAnySet_CheckExact(other)) {
1428 Py_ssize_t pos = 0;
1429 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1432 tmp = (PyObject *)so;
1433 so = (PySetObject *)other;
1434 other = tmp;
1435 }
1436 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001437 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001438 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 return NULL;
1440 if (rv)
1441 Py_RETURN_FALSE;
1442 }
1443 Py_RETURN_TRUE;
1444 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 it = PyObject_GetIter(other);
1447 if (it == NULL)
1448 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001451 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001452
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 if (hash == -1) {
1454 Py_DECREF(key);
1455 Py_DECREF(it);
1456 return NULL;
1457 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001458 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001460 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 Py_DECREF(it);
1462 return NULL;
1463 }
1464 if (rv) {
1465 Py_DECREF(it);
1466 Py_RETURN_FALSE;
1467 }
1468 }
1469 Py_DECREF(it);
1470 if (PyErr_Occurred())
1471 return NULL;
1472 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001473}
1474
1475PyDoc_STRVAR(isdisjoint_doc,
1476"Return True if two sets have a null intersection.");
1477
Neal Norwitz6576bd82005-11-13 18:41:28 +00001478static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001479set_difference_update_internal(PySetObject *so, PyObject *other)
1480{
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001481 if (PySet_GET_SIZE(so) == 0) {
1482 return 0;
1483 }
1484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if ((PyObject *)so == other)
1486 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 if (PyAnySet_Check(other)) {
1489 setentry *entry;
1490 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001493 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 return -1;
1495 } else {
1496 PyObject *key, *it;
1497 it = PyObject_GetIter(other);
1498 if (it == NULL)
1499 return -1;
1500
1501 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001502 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 Py_DECREF(it);
1504 Py_DECREF(key);
1505 return -1;
1506 }
1507 Py_DECREF(key);
1508 }
1509 Py_DECREF(it);
1510 if (PyErr_Occurred())
1511 return -1;
1512 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001513 /* If more than 1/4th are dummies, then resize them away. */
1514 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 return 0;
INADA Naokie82cf862017-04-01 17:20:25 +09001516 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001517}
1518
Raymond Hettingera690a992003-11-16 16:17:49 +00001519static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001520set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001521{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001523
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1525 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001526 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 return NULL;
1528 }
1529 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001530}
1531
1532PyDoc_STRVAR(difference_update_doc,
1533"Remove all elements of another set from this set.");
1534
1535static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001536set_copy_and_difference(PySetObject *so, PyObject *other)
1537{
1538 PyObject *result;
1539
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301540 result = set_copy(so, NULL);
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001541 if (result == NULL)
1542 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001543 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001544 return result;
1545 Py_DECREF(result);
1546 return NULL;
1547}
1548
1549static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001550set_difference(PySetObject *so, PyObject *other)
1551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001553 PyObject *key;
1554 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001555 setentry *entry;
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001556 Py_ssize_t pos = 0, other_size;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001557 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001558
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001559 if (PySet_GET_SIZE(so) == 0) {
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301560 return set_copy(so, NULL);
Raymond Hettinger4103e4d2016-09-11 22:02:28 -07001561 }
1562
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001563 if (PyAnySet_Check(other)) {
1564 other_size = PySet_GET_SIZE(other);
1565 }
1566 else if (PyDict_CheckExact(other)) {
1567 other_size = PyDict_GET_SIZE(other);
1568 }
1569 else {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001570 return set_copy_and_difference(so, other);
1571 }
1572
1573 /* If len(so) much more than len(other), it's more efficient to simply copy
1574 * so and then iterate other looking for common elements. */
Serhiy Storchakabf623ae2017-04-19 20:03:52 +03001575 if ((PySet_GET_SIZE(so) >> 2) > other_size) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001576 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001578
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 result = make_new_set_basetype(Py_TYPE(so), NULL);
1580 if (result == NULL)
1581 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 if (PyDict_CheckExact(other)) {
1584 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001585 key = entry->key;
1586 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001587 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001588 if (rv < 0) {
1589 Py_DECREF(result);
1590 return NULL;
1591 }
1592 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001593 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 Py_DECREF(result);
1595 return NULL;
1596 }
1597 }
1598 }
1599 return result;
1600 }
1601
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001602 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001603 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001604 key = entry->key;
1605 hash = entry->hash;
1606 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001607 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001608 Py_DECREF(result);
1609 return NULL;
1610 }
1611 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001612 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 Py_DECREF(result);
1614 return NULL;
1615 }
1616 }
1617 }
1618 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001619}
1620
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001621static PyObject *
1622set_difference_multi(PySetObject *so, PyObject *args)
1623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 Py_ssize_t i;
1625 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001627 if (PyTuple_GET_SIZE(args) == 0)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301628 return set_copy(so, NULL);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 other = PyTuple_GET_ITEM(args, 0);
1631 result = set_difference(so, other);
1632 if (result == NULL)
1633 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001635 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1636 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001637 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001638 Py_DECREF(result);
1639 return NULL;
1640 }
1641 }
1642 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001643}
1644
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001645PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001646"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001647\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001648(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001649static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001650set_sub(PySetObject *so, PyObject *other)
1651{
Brian Curtindfc80e32011-08-10 20:28:54 -05001652 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1653 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001655}
1656
1657static PyObject *
1658set_isub(PySetObject *so, PyObject *other)
1659{
Brian Curtindfc80e32011-08-10 20:28:54 -05001660 if (!PyAnySet_Check(other))
1661 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001662 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001663 return NULL;
1664 Py_INCREF(so);
1665 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001666}
1667
1668static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001669set_symmetric_difference_update(PySetObject *so, PyObject *other)
1670{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001671 PySetObject *otherset;
1672 PyObject *key;
1673 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001674 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001676 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001677
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 if ((PyObject *)so == other)
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301679 return set_clear(so, NULL);
Raymond Hettingera690a992003-11-16 16:17:49 +00001680
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001681 if (PyDict_CheckExact(other)) {
1682 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001684 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001685 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001686 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001687 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001690 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001691 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001692 Py_DECREF(key);
1693 return NULL;
1694 }
1695 }
Georg Brandl2d444492010-09-03 10:52:55 +00001696 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001697 }
1698 Py_RETURN_NONE;
1699 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001700
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 if (PyAnySet_Check(other)) {
1702 Py_INCREF(other);
1703 otherset = (PySetObject *)other;
1704 } else {
1705 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1706 if (otherset == NULL)
1707 return NULL;
1708 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001709
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001710 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001711 key = entry->key;
1712 hash = entry->hash;
1713 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001714 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001715 Py_DECREF(otherset);
1716 return NULL;
1717 }
1718 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001719 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 Py_DECREF(otherset);
1721 return NULL;
1722 }
1723 }
1724 }
1725 Py_DECREF(otherset);
1726 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001727}
1728
1729PyDoc_STRVAR(symmetric_difference_update_doc,
1730"Update a set with the symmetric difference of itself and another.");
1731
1732static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001733set_symmetric_difference(PySetObject *so, PyObject *other)
1734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 PyObject *rv;
1736 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1739 if (otherset == NULL)
1740 return NULL;
1741 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
lekma491bbed2018-05-02 11:29:10 +02001742 if (rv == NULL) {
1743 Py_DECREF(otherset);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001744 return NULL;
lekma491bbed2018-05-02 11:29:10 +02001745 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 Py_DECREF(rv);
1747 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001748}
1749
1750PyDoc_STRVAR(symmetric_difference_doc,
1751"Return the symmetric difference of two sets as a new set.\n\
1752\n\
1753(i.e. all elements that are in exactly one of the sets.)");
1754
1755static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001756set_xor(PySetObject *so, PyObject *other)
1757{
Brian Curtindfc80e32011-08-10 20:28:54 -05001758 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1759 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001760 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001761}
1762
1763static PyObject *
1764set_ixor(PySetObject *so, PyObject *other)
1765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001767
Brian Curtindfc80e32011-08-10 20:28:54 -05001768 if (!PyAnySet_Check(other))
1769 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 result = set_symmetric_difference_update(so, other);
1771 if (result == NULL)
1772 return NULL;
1773 Py_DECREF(result);
1774 Py_INCREF(so);
1775 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001776}
1777
1778static PyObject *
1779set_issubset(PySetObject *so, PyObject *other)
1780{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001781 setentry *entry;
1782 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001783 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001784
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001785 if (!PyAnySet_Check(other)) {
1786 PyObject *tmp, *result;
1787 tmp = make_new_set(&PySet_Type, other);
1788 if (tmp == NULL)
1789 return NULL;
1790 result = set_issubset(so, tmp);
1791 Py_DECREF(tmp);
1792 return result;
1793 }
1794 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1795 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001798 rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001799 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001800 return NULL;
1801 if (!rv)
1802 Py_RETURN_FALSE;
1803 }
1804 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001805}
1806
1807PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1808
1809static PyObject *
1810set_issuperset(PySetObject *so, PyObject *other)
1811{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001812 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001814 if (!PyAnySet_Check(other)) {
1815 tmp = make_new_set(&PySet_Type, other);
1816 if (tmp == NULL)
1817 return NULL;
1818 result = set_issuperset(so, tmp);
1819 Py_DECREF(tmp);
1820 return result;
1821 }
1822 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001823}
1824
1825PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1826
Raymond Hettingera690a992003-11-16 16:17:49 +00001827static PyObject *
1828set_richcompare(PySetObject *v, PyObject *w, int op)
1829{
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001830 PyObject *r1;
1831 int r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001832
Brian Curtindfc80e32011-08-10 20:28:54 -05001833 if(!PyAnySet_Check(w))
1834 Py_RETURN_NOTIMPLEMENTED;
1835
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 switch (op) {
1837 case Py_EQ:
1838 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1839 Py_RETURN_FALSE;
1840 if (v->hash != -1 &&
1841 ((PySetObject *)w)->hash != -1 &&
1842 v->hash != ((PySetObject *)w)->hash)
1843 Py_RETURN_FALSE;
1844 return set_issubset(v, w);
1845 case Py_NE:
1846 r1 = set_richcompare(v, w, Py_EQ);
1847 if (r1 == NULL)
1848 return NULL;
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001849 r2 = PyObject_IsTrue(r1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 Py_DECREF(r1);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001851 if (r2 < 0)
1852 return NULL;
1853 return PyBool_FromLong(!r2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 case Py_LE:
1855 return set_issubset(v, w);
1856 case Py_GE:
1857 return set_issuperset(v, w);
1858 case Py_LT:
1859 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1860 Py_RETURN_FALSE;
1861 return set_issubset(v, w);
1862 case Py_GT:
1863 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1864 Py_RETURN_FALSE;
1865 return set_issuperset(v, w);
1866 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001867 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001868}
1869
Raymond Hettingera690a992003-11-16 16:17:49 +00001870static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001871set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001872{
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001873 if (set_add_key(so, key))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001874 return NULL;
1875 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001876}
1877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001879"Add an element to a set.\n\
1880\n\
1881This has no effect if the element is already present.");
1882
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001883static int
1884set_contains(PySetObject *so, PyObject *key)
1885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 PyObject *tmpkey;
1887 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 rv = set_contains_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001890 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1892 return -1;
1893 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001894 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 if (tmpkey == NULL)
1896 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001897 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 Py_DECREF(tmpkey);
1899 }
1900 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001901}
1902
1903static PyObject *
1904set_direct_contains(PySetObject *so, PyObject *key)
1905{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 result = set_contains(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001909 if (result < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 return NULL;
1911 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001912}
1913
1914PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1915
Raymond Hettingera690a992003-11-16 16:17:49 +00001916static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001917set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001918{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 PyObject *tmpkey;
1920 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001923 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1925 return NULL;
1926 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001927 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 if (tmpkey == NULL)
1929 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001932 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 return NULL;
1934 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001935
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001937 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 return NULL;
1939 }
1940 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001941}
1942
1943PyDoc_STRVAR(remove_doc,
1944"Remove an element from a set; it must be a member.\n\
1945\n\
1946If the element is not a member, raise a KeyError.");
1947
1948static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001949set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001950{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001951 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 rv = set_discard_key(so, key);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001955 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1957 return NULL;
1958 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001959 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 if (tmpkey == NULL)
1961 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001962 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 Py_DECREF(tmpkey);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001964 if (rv < 0)
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001965 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 }
1967 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001968}
1969
1970PyDoc_STRVAR(discard_doc,
1971"Remove an element from a set if it is a member.\n\
1972\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001974
1975static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301976set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingera690a992003-11-16 16:17:49 +00001977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001979 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001981 keys = PySequence_List((PyObject *)so);
1982 if (keys == NULL)
1983 goto done;
1984 args = PyTuple_Pack(1, keys);
1985 if (args == NULL)
1986 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001987 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 if (dict == NULL) {
1989 PyErr_Clear();
1990 dict = Py_None;
1991 Py_INCREF(dict);
1992 }
1993 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001994done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 Py_XDECREF(args);
1996 Py_XDECREF(keys);
1997 Py_XDECREF(dict);
1998 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001999}
2000
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002001static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302002set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002005
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002006 res = _PyObject_SIZE(Py_TYPE(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002007 if (so->table != so->smalltable)
2008 res = res + (so->mask + 1) * sizeof(setentry);
2009 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002010}
2011
2012PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002013static int
2014set_init(PySetObject *self, PyObject *args, PyObject *kwds)
2015{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002017
Serhiy Storchaka6cca5c82017-06-08 14:41:19 +03002018 if (!_PyArg_NoKeywords("set", kwds))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 return -1;
2020 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2021 return -1;
Raymond Hettingerb72e21b2016-03-25 02:29:59 -07002022 if (self->fill)
2023 set_clear_internal(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 self->hash = -1;
2025 if (iterable == NULL)
2026 return 0;
2027 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002028}
2029
Raymond Hettingera690a992003-11-16 16:17:49 +00002030static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 set_len, /* sq_length */
2032 0, /* sq_concat */
2033 0, /* sq_repeat */
2034 0, /* sq_item */
2035 0, /* sq_slice */
2036 0, /* sq_ass_item */
2037 0, /* sq_ass_slice */
2038 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002039};
2040
2041/* set object ********************************************************/
2042
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002043#ifdef Py_DEBUG
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302044static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002045
2046PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2047All is well if assertions don't fail.");
2048#endif
2049
Raymond Hettingera690a992003-11-16 16:17:49 +00002050static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002051 {"add", (PyCFunction)set_add, METH_O,
2052 add_doc},
2053 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2054 clear_doc},
2055 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2056 contains_doc},
2057 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2058 copy_doc},
2059 {"discard", (PyCFunction)set_discard, METH_O,
2060 discard_doc},
2061 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2062 difference_doc},
2063 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2064 difference_update_doc},
2065 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2066 intersection_doc},
2067 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2068 intersection_update_doc},
2069 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2070 isdisjoint_doc},
2071 {"issubset", (PyCFunction)set_issubset, METH_O,
2072 issubset_doc},
2073 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2074 issuperset_doc},
2075 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2076 pop_doc},
2077 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2078 reduce_doc},
2079 {"remove", (PyCFunction)set_remove, METH_O,
2080 remove_doc},
2081 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2082 sizeof_doc},
2083 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2084 symmetric_difference_doc},
2085 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2086 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002087#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2089 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002090#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 {"union", (PyCFunction)set_union, METH_VARARGS,
2092 union_doc},
2093 {"update", (PyCFunction)set_update, METH_VARARGS,
2094 update_doc},
2095 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002096};
2097
2098static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 0, /*nb_add*/
2100 (binaryfunc)set_sub, /*nb_subtract*/
2101 0, /*nb_multiply*/
2102 0, /*nb_remainder*/
2103 0, /*nb_divmod*/
2104 0, /*nb_power*/
2105 0, /*nb_negative*/
2106 0, /*nb_positive*/
2107 0, /*nb_absolute*/
2108 0, /*nb_bool*/
2109 0, /*nb_invert*/
2110 0, /*nb_lshift*/
2111 0, /*nb_rshift*/
2112 (binaryfunc)set_and, /*nb_and*/
2113 (binaryfunc)set_xor, /*nb_xor*/
2114 (binaryfunc)set_or, /*nb_or*/
2115 0, /*nb_int*/
2116 0, /*nb_reserved*/
2117 0, /*nb_float*/
2118 0, /*nb_inplace_add*/
2119 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2120 0, /*nb_inplace_multiply*/
2121 0, /*nb_inplace_remainder*/
2122 0, /*nb_inplace_power*/
2123 0, /*nb_inplace_lshift*/
2124 0, /*nb_inplace_rshift*/
2125 (binaryfunc)set_iand, /*nb_inplace_and*/
2126 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2127 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002128};
2129
2130PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002131"set() -> new empty set object\n\
2132set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002133\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002134Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002135
2136PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2138 "set", /* tp_name */
2139 sizeof(PySetObject), /* tp_basicsize */
2140 0, /* tp_itemsize */
2141 /* methods */
2142 (destructor)set_dealloc, /* tp_dealloc */
2143 0, /* tp_print */
2144 0, /* tp_getattr */
2145 0, /* tp_setattr */
2146 0, /* tp_reserved */
2147 (reprfunc)set_repr, /* tp_repr */
2148 &set_as_number, /* tp_as_number */
2149 &set_as_sequence, /* tp_as_sequence */
2150 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002151 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002152 0, /* tp_call */
2153 0, /* tp_str */
2154 PyObject_GenericGetAttr, /* tp_getattro */
2155 0, /* tp_setattro */
2156 0, /* tp_as_buffer */
2157 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2158 Py_TPFLAGS_BASETYPE, /* tp_flags */
2159 set_doc, /* tp_doc */
2160 (traverseproc)set_traverse, /* tp_traverse */
2161 (inquiry)set_clear_internal, /* tp_clear */
2162 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002163 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2164 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 0, /* tp_iternext */
2166 set_methods, /* tp_methods */
2167 0, /* tp_members */
2168 0, /* tp_getset */
2169 0, /* tp_base */
2170 0, /* tp_dict */
2171 0, /* tp_descr_get */
2172 0, /* tp_descr_set */
2173 0, /* tp_dictoffset */
2174 (initproc)set_init, /* tp_init */
2175 PyType_GenericAlloc, /* tp_alloc */
2176 set_new, /* tp_new */
2177 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002178};
2179
2180/* frozenset object ********************************************************/
2181
2182
2183static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002184 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2185 contains_doc},
2186 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2187 copy_doc},
2188 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2189 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002190 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 intersection_doc},
2192 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2193 isdisjoint_doc},
2194 {"issubset", (PyCFunction)set_issubset, METH_O,
2195 issubset_doc},
2196 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2197 issuperset_doc},
2198 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2199 reduce_doc},
2200 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2201 sizeof_doc},
2202 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2203 symmetric_difference_doc},
2204 {"union", (PyCFunction)set_union, METH_VARARGS,
2205 union_doc},
2206 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002207};
2208
2209static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002210 0, /*nb_add*/
2211 (binaryfunc)set_sub, /*nb_subtract*/
2212 0, /*nb_multiply*/
2213 0, /*nb_remainder*/
2214 0, /*nb_divmod*/
2215 0, /*nb_power*/
2216 0, /*nb_negative*/
2217 0, /*nb_positive*/
2218 0, /*nb_absolute*/
2219 0, /*nb_bool*/
2220 0, /*nb_invert*/
2221 0, /*nb_lshift*/
2222 0, /*nb_rshift*/
2223 (binaryfunc)set_and, /*nb_and*/
2224 (binaryfunc)set_xor, /*nb_xor*/
2225 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002226};
2227
2228PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002229"frozenset() -> empty frozenset object\n\
2230frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002231\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002232Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002233
2234PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2236 "frozenset", /* tp_name */
2237 sizeof(PySetObject), /* tp_basicsize */
2238 0, /* tp_itemsize */
2239 /* methods */
2240 (destructor)set_dealloc, /* tp_dealloc */
2241 0, /* tp_print */
2242 0, /* tp_getattr */
2243 0, /* tp_setattr */
2244 0, /* tp_reserved */
2245 (reprfunc)set_repr, /* tp_repr */
2246 &frozenset_as_number, /* tp_as_number */
2247 &set_as_sequence, /* tp_as_sequence */
2248 0, /* tp_as_mapping */
2249 frozenset_hash, /* tp_hash */
2250 0, /* tp_call */
2251 0, /* tp_str */
2252 PyObject_GenericGetAttr, /* tp_getattro */
2253 0, /* tp_setattro */
2254 0, /* tp_as_buffer */
2255 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2256 Py_TPFLAGS_BASETYPE, /* tp_flags */
2257 frozenset_doc, /* tp_doc */
2258 (traverseproc)set_traverse, /* tp_traverse */
2259 (inquiry)set_clear_internal, /* tp_clear */
2260 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002261 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002262 (getiterfunc)set_iter, /* tp_iter */
2263 0, /* tp_iternext */
2264 frozenset_methods, /* tp_methods */
2265 0, /* tp_members */
2266 0, /* tp_getset */
2267 0, /* tp_base */
2268 0, /* tp_dict */
2269 0, /* tp_descr_get */
2270 0, /* tp_descr_set */
2271 0, /* tp_dictoffset */
2272 0, /* tp_init */
2273 PyType_GenericAlloc, /* tp_alloc */
2274 frozenset_new, /* tp_new */
2275 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002276};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002277
2278
2279/***** C API functions *************************************************/
2280
2281PyObject *
2282PySet_New(PyObject *iterable)
2283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002284 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002285}
2286
2287PyObject *
2288PyFrozenSet_New(PyObject *iterable)
2289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002290 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002291}
2292
Neal Norwitz8c49c822006-03-04 18:41:19 +00002293Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002294PySet_Size(PyObject *anyset)
2295{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002296 if (!PyAnySet_Check(anyset)) {
2297 PyErr_BadInternalCall();
2298 return -1;
2299 }
2300 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002301}
2302
2303int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002304PySet_Clear(PyObject *set)
2305{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 if (!PySet_Check(set)) {
2307 PyErr_BadInternalCall();
2308 return -1;
2309 }
2310 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002311}
2312
2313int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002314PySet_Contains(PyObject *anyset, PyObject *key)
2315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 if (!PyAnySet_Check(anyset)) {
2317 PyErr_BadInternalCall();
2318 return -1;
2319 }
2320 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002321}
2322
2323int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002324PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002325{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002326 if (!PySet_Check(set)) {
2327 PyErr_BadInternalCall();
2328 return -1;
2329 }
2330 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002331}
2332
2333int
Christian Heimesfd66e512008-01-29 12:18:50 +00002334PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 if (!PySet_Check(anyset) &&
2337 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2338 PyErr_BadInternalCall();
2339 return -1;
2340 }
2341 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002342}
2343
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002344int
Raymond Hettinger3625af52016-03-27 01:15:07 -07002345PySet_ClearFreeList(void)
2346{
2347 return 0;
2348}
2349
2350void
2351PySet_Fini(void)
2352{
2353 Py_CLEAR(emptyfrozenset);
2354}
2355
2356int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002357_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002358{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 if (!PyAnySet_Check(set)) {
2362 PyErr_BadInternalCall();
2363 return -1;
2364 }
2365 if (set_next((PySetObject *)set, pos, &entry) == 0)
2366 return 0;
2367 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002368 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002370}
2371
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002372PyObject *
2373PySet_Pop(PyObject *set)
2374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 if (!PySet_Check(set)) {
2376 PyErr_BadInternalCall();
2377 return NULL;
2378 }
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302379 return set_pop((PySetObject *)set, NULL);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002380}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002381
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002382int
2383_PySet_Update(PyObject *set, PyObject *iterable)
2384{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 if (!PySet_Check(set)) {
2386 PyErr_BadInternalCall();
2387 return -1;
2388 }
2389 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002390}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002391
Raymond Hettingere259f132013-12-15 11:56:14 -08002392/* Exported for the gdb plugin's benefit. */
2393PyObject *_PySet_Dummy = dummy;
2394
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002395#ifdef Py_DEBUG
2396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002398 Returns True and original set is restored. */
2399
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002400#define assertRaises(call_return_value, exception) \
2401 do { \
2402 assert(call_return_value); \
2403 assert(PyErr_ExceptionMatches(exception)); \
2404 PyErr_Clear(); \
2405 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002406
2407static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05302408test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002410 Py_ssize_t count;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +02002411 const char *s;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002413 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002414 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002415 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 /* Verify preconditions */
2419 assert(PyAnySet_Check(ob));
2420 assert(PyAnySet_CheckExact(ob));
2421 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* so.clear(); so |= set("abc"); */
2424 str = PyUnicode_FromString("abc");
2425 if (str == NULL)
2426 return NULL;
2427 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002428 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 Py_DECREF(str);
2430 return NULL;
2431 }
2432 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002434 /* Exercise type/size checks */
2435 assert(PySet_Size(ob) == 3);
2436 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 /* Raise TypeError for non-iterable constructor arguments */
2439 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2440 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002442 /* Raise TypeError for unhashable key */
2443 dup = PySet_New(ob);
2444 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2445 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2446 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002447
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002448 /* Exercise successful pop, contains, add, and discard */
2449 elem = PySet_Pop(ob);
2450 assert(PySet_Contains(ob, elem) == 0);
2451 assert(PySet_GET_SIZE(ob) == 2);
2452 assert(PySet_Add(ob, elem) == 0);
2453 assert(PySet_Contains(ob, elem) == 1);
2454 assert(PySet_GET_SIZE(ob) == 3);
2455 assert(PySet_Discard(ob, elem) == 1);
2456 assert(PySet_GET_SIZE(ob) == 2);
2457 assert(PySet_Discard(ob, elem) == 0);
2458 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002460 /* Exercise clear */
2461 dup2 = PySet_New(dup);
2462 assert(PySet_Clear(dup2) == 0);
2463 assert(PySet_Size(dup2) == 0);
2464 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002466 /* Raise SystemError on clear or update of frozen set */
2467 f = PyFrozenSet_New(dup);
2468 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2469 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2470 assert(PySet_Add(f, elem) == 0);
2471 Py_INCREF(f);
2472 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2473 Py_DECREF(f);
2474 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002475
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002476 /* Exercise direct iteration */
2477 i = 0, count = 0;
2478 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
Serhiy Storchaka06515832016-11-20 09:13:07 +02002479 s = PyUnicode_AsUTF8(x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002480 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2481 count++;
2482 }
2483 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002485 /* Exercise updates */
2486 dup2 = PySet_New(NULL);
2487 assert(_PySet_Update(dup2, dup) == 0);
2488 assert(PySet_Size(dup2) == 3);
2489 assert(_PySet_Update(dup2, dup) == 0);
2490 assert(PySet_Size(dup2) == 3);
2491 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002493 /* Raise SystemError when self argument is not a set or frozenset. */
2494 t = PyTuple_New(0);
2495 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2496 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2497 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002499 /* Raise SystemError when self argument is not a set. */
2500 f = PyFrozenSet_New(dup);
2501 assert(PySet_Size(f) == 3);
2502 assert(PyFrozenSet_CheckExact(f));
2503 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2504 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2505 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002506
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002507 /* Raise KeyError when popping from an empty set */
2508 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2509 Py_DECREF(ob);
2510 assert(PySet_GET_SIZE(ob) == 0);
2511 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002513 /* Restore the set from the copy using the PyNumber API */
2514 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2515 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 /* Verify constructors accept NULL arguments */
2518 f = PySet_New(NULL);
2519 assert(f != NULL);
2520 assert(PySet_GET_SIZE(f) == 0);
2521 Py_DECREF(f);
2522 f = PyFrozenSet_New(NULL);
2523 assert(f != NULL);
2524 assert(PyFrozenSet_CheckExact(f));
2525 assert(PySet_GET_SIZE(f) == 0);
2526 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002528 Py_DECREF(elem);
2529 Py_DECREF(dup);
2530 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002531}
2532
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002533#undef assertRaises
2534
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002535#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002536
2537/***** Dummy Struct *************************************************/
2538
2539static PyObject *
2540dummy_repr(PyObject *op)
2541{
2542 return PyUnicode_FromString("<dummy key>");
2543}
2544
2545static void
2546dummy_dealloc(PyObject* ignore)
2547{
2548 Py_FatalError("deallocating <dummy key>");
2549}
2550
2551static PyTypeObject _PySetDummy_Type = {
2552 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2553 "<dummy key> type",
2554 0,
2555 0,
2556 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2557 0, /*tp_print*/
2558 0, /*tp_getattr*/
2559 0, /*tp_setattr*/
2560 0, /*tp_reserved*/
2561 dummy_repr, /*tp_repr*/
2562 0, /*tp_as_number*/
2563 0, /*tp_as_sequence*/
2564 0, /*tp_as_mapping*/
2565 0, /*tp_hash */
2566 0, /*tp_call */
2567 0, /*tp_str */
2568 0, /*tp_getattro */
2569 0, /*tp_setattro */
2570 0, /*tp_as_buffer */
2571 Py_TPFLAGS_DEFAULT, /*tp_flags */
2572};
2573
2574static PyObject _dummy_struct = {
2575 _PyObject_EXTRA_INIT
2576 2, &_PySetDummy_Type
2577};
2578