blob: 4723b584b88eba5ad1403acb77667a43f34c30cb [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 Hettingerbd9b2002015-01-18 16:10:30 -08007 Copyright (c) 2003-2015 Python Software Foundation.
Raymond Hettingera9d99362005-08-05 00:01:15 +00008 All rights reserved.
Raymond Hettingerae7b00e2013-09-07 15:05:00 -07009
10 The basic lookup function used by all operations.
11 This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
12
13 The initial probe index is computed as hash mod the table size.
14 Subsequent probe indices are computed as explained in Objects/dictobject.c.
15
16 To improve cache locality, each probe inspects a series of consecutive
17 nearby entries before moving on to probes elsewhere in memory. This leaves
18 us with a hybrid of linear probing and open addressing. The linear probing
19 reduces the cost of hash collisions because consecutive memory accesses
20 tend to be much cheaper than scattered probes. After LINEAR_PROBES steps,
21 we then use open addressing with the upper bits from the hash value. This
22 helps break-up long chains of collisions.
23
24 All arithmetic on hash should ignore overflow.
25
Raymond Hettinger4d45c102015-01-25 16:27:40 -080026 Unlike the dictionary implementation, the lookkey function can return
Raymond Hettingerae7b00e2013-09-07 15:05:00 -070027 NULL if the rich comparison returns an error.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000028*/
29
Raymond Hettingera690a992003-11-16 16:17:49 +000030#include "Python.h"
Raymond Hettingera9d99362005-08-05 00:01:15 +000031#include "structmember.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000032
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000033/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050034static PyObject _dummy_struct;
35
36#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000037
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070039/* ======================================================================== */
40/* ======= Begin logic for probing the hash table ========================= */
41
Raymond Hettinger710a67e2013-09-21 20:17:31 -070042/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070043#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070044#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070045#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070046
47/* This must be >= 1 */
48#define PERTURB_SHIFT 5
49
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000050static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020051set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000052{
Raymond Hettinger70559b52015-07-23 07:42:23 -040053 setentry *table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020054 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070055 size_t perturb;
Raymond Hettingerafe89092013-08-28 20:59:31 -070056 size_t mask = so->mask;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -080057 size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070058 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070059 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000060
Raymond Hettinger70559b52015-07-23 07:42:23 -040061 entry = &so->table[i];
Raymond Hettingerafe89092013-08-28 20:59:31 -070062 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070064
Raymond Hettinger38bb95e2015-06-24 01:22:19 -070065 perturb = hash;
66
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070067 while (1) {
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080068 if (entry->hash == hash) {
Raymond Hettingerafe89092013-08-28 20:59:31 -070069 PyObject *startkey = entry->key;
Raymond Hettingera5ebbf62015-01-26 21:54:35 -080070 /* startkey cannot be a dummy because the dummy hash field is -1 */
71 assert(startkey != dummy);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080072 if (startkey == key)
73 return entry;
Raymond Hettinger93035c42015-01-25 16:12:49 -080074 if (PyUnicode_CheckExact(startkey)
75 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -070076 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger93035c42015-01-25 16:12:49 -080077 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -040078 table = so->table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 Py_INCREF(startkey);
80 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
81 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010082 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010084 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010086 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070087 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -060088 mask = so->mask; /* help avoid a register spill */
Raymond Hettingerafe89092013-08-28 20:59:31 -070089 }
Raymond Hettingerafe89092013-08-28 20:59:31 -070090
Raymond Hettingerc658d852015-02-02 08:35:00 -080091 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -080092 for (j = 0 ; j < LINEAR_PROBES ; j++) {
Raymond Hettingerc658d852015-02-02 08:35:00 -080093 entry++;
Raymond Hettinger8651a502015-05-27 10:37:20 -070094 if (entry->hash == 0 && entry->key == NULL)
95 return entry;
Raymond Hettingerc658d852015-02-02 08:35:00 -080096 if (entry->hash == hash) {
97 PyObject *startkey = entry->key;
98 assert(startkey != dummy);
99 if (startkey == key)
100 return entry;
101 if (PyUnicode_CheckExact(startkey)
102 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700103 && _PyUnicode_EQ(startkey, key))
Raymond Hettingerc658d852015-02-02 08:35:00 -0800104 return entry;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400105 table = so->table;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800106 Py_INCREF(startkey);
107 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
108 Py_DECREF(startkey);
109 if (cmp < 0)
110 return NULL;
111 if (table != so->table || entry->key != startkey)
112 return set_lookkey(so, key, hash);
113 if (cmp > 0)
114 return entry;
Raymond Hettinger438f9132015-02-09 06:48:29 -0600115 mask = so->mask;
Raymond Hettingerc658d852015-02-02 08:35:00 -0800116 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700117 }
118 }
119
120 perturb >>= PERTURB_SHIFT;
121 i = (i * 5 + 1 + perturb) & mask;
122
Raymond Hettinger70559b52015-07-23 07:42:23 -0400123 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700124 if (entry->key == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700125 return entry;
126 }
127}
128
Raymond Hettinger15f08692015-07-03 17:21:17 -0700129static int set_table_resize(PySetObject *, Py_ssize_t);
130
Raymond Hettinger8651a502015-05-27 10:37:20 -0700131static int
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400132set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700133{
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400134 setentry *table;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700135 setentry *freeslot;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700136 setentry *entry;
Raymond Hettinger38bb95e2015-06-24 01:22:19 -0700137 size_t perturb;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400138 size_t mask;
139 size_t i; /* Unsigned for defined overflow behavior */
Raymond Hettinger8651a502015-05-27 10:37:20 -0700140 size_t j;
141 int cmp;
142
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400143 /* Pre-increment is necessary to prevent arbitrary code in the rich
144 comparison from deallocating the key just before the insertion. */
145 Py_INCREF(key);
146
147 restart:
148
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400149 mask = so->mask;
150 i = (size_t)hash & mask;
151
Raymond Hettinger70559b52015-07-23 07:42:23 -0400152 entry = &so->table[i];
Raymond Hettinger8651a502015-05-27 10:37:20 -0700153 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700154 goto found_unused;
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700155
156 freeslot = NULL;
157 perturb = hash;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700158
159 while (1) {
160 if (entry->hash == hash) {
161 PyObject *startkey = entry->key;
162 /* startkey cannot be a dummy because the dummy hash field is -1 */
163 assert(startkey != dummy);
164 if (startkey == key)
165 goto found_active;
166 if (PyUnicode_CheckExact(startkey)
167 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700168 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700169 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400170 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700171 Py_INCREF(startkey);
172 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
173 Py_DECREF(startkey);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700174 if (cmp > 0) /* likely */
175 goto found_active;
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700176 if (cmp < 0)
177 goto comparison_error;
178 /* Continuing the search from the current entry only makes
179 sense if the table and entry are unchanged; otherwise,
180 we have to restart from the beginning */
181 if (table != so->table || entry->key != startkey)
182 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700183 mask = so->mask; /* help avoid a register spill */
184 }
Raymond Hettinger70559b52015-07-23 07:42:23 -0400185 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettinger8651a502015-05-27 10:37:20 -0700186 freeslot = entry;
187
188 if (i + LINEAR_PROBES <= mask) {
189 for (j = 0 ; j < LINEAR_PROBES ; j++) {
190 entry++;
191 if (entry->hash == 0 && entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700192 goto found_unused_or_dummy;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700193 if (entry->hash == hash) {
194 PyObject *startkey = entry->key;
195 assert(startkey != dummy);
196 if (startkey == key)
197 goto found_active;
198 if (PyUnicode_CheckExact(startkey)
199 && PyUnicode_CheckExact(key)
Raymond Hettingerac2ef652015-07-04 16:04:44 -0700200 && _PyUnicode_EQ(startkey, key))
Raymond Hettinger8651a502015-05-27 10:37:20 -0700201 goto found_active;
Raymond Hettinger70559b52015-07-23 07:42:23 -0400202 table = so->table;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700203 Py_INCREF(startkey);
204 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
205 Py_DECREF(startkey);
Raymond Hettingerdaffc912015-07-31 07:58:56 -0700206 if (cmp > 0)
207 goto found_active;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700208 if (cmp < 0)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400209 goto comparison_error;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700210 if (table != so->table || entry->key != startkey)
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400211 goto restart;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700212 mask = so->mask;
213 }
Raymond Hettinger91672612015-06-26 02:50:21 -0700214 else if (entry->hash == -1 && freeslot == NULL)
Raymond Hettingerc658d852015-02-02 08:35:00 -0800215 freeslot = entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700216 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700218
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700219 perturb >>= PERTURB_SHIFT;
Raymond Hettinger59ecabd2015-01-31 02:45:12 -0800220 i = (i * 5 + 1 + perturb) & mask;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700221
Raymond Hettinger70559b52015-07-23 07:42:23 -0400222 entry = &so->table[i];
Raymond Hettinger7e3592d2015-06-21 10:47:20 -0700223 if (entry->key == NULL)
Raymond Hettinger15f08692015-07-03 17:21:17 -0700224 goto found_unused_or_dummy;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 }
Raymond Hettinger8651a502015-05-27 10:37:20 -0700226
Raymond Hettinger15f08692015-07-03 17:21:17 -0700227 found_unused_or_dummy:
228 if (freeslot == NULL)
229 goto found_unused;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700230 so->used++;
231 freeslot->key = key;
232 freeslot->hash = hash;
233 return 0;
234
235 found_unused:
Raymond Hettinger6ee588f2015-06-20 21:39:51 -0700236 so->fill++;
237 so->used++;
238 entry->key = key;
239 entry->hash = hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -0700240 if ((size_t)so->fill*3 < mask*2)
241 return 0;
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400242 return set_table_resize(so, so->used);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700243
244 found_active:
Raymond Hettinger482c05c2015-07-20 01:23:32 -0400245 Py_DECREF(key);
Raymond Hettinger8651a502015-05-27 10:37:20 -0700246 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000247
Raymond Hettingerff9e18a2015-07-20 07:34:05 -0400248 comparison_error:
Raymond Hettinger061091a2015-07-15 23:54:02 -0700249 Py_DECREF(key);
250 return -1;
251}
252
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000254Internal routine used by set_table_resize() to insert an item which is
255known to be absent from the set. This routine also assumes that
256the set contains no deleted entries. Besides the performance benefit,
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800257there is also safety benefit since using set_add_entry() risks making
258a callback in the middle of a set_table_resize(), see issue 1456209.
259The caller is responsible for updating the key's reference count and
260the setobject's fill and used fields.
Thomas Wouters89f507f2006-12-13 04:49:30 +0000261*/
262static void
Raymond Hettinger5088f602015-12-13 18:45:01 -0800263set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000264{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200265 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700266 size_t perturb = hash;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800267 size_t i = (size_t)hash & mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700268 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000269
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700270 while (1) {
Raymond Hettinger3037e842015-01-26 21:33:48 -0800271 entry = &table[i];
272 if (entry->key == NULL)
273 goto found_null;
274 if (i + LINEAR_PROBES <= mask) {
Raymond Hettinger82492822015-02-04 08:37:02 -0800275 for (j = 0; j < LINEAR_PROBES; j++) {
Raymond Hettinger9edd7532015-01-30 20:09:23 -0800276 entry++;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800277 if (entry->key == NULL)
278 goto found_null;
279 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700280 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700281 perturb >>= PERTURB_SHIFT;
Raymond Hettinger3037e842015-01-26 21:33:48 -0800282 i = (i * 5 + 1 + perturb) & mask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700284 found_null:
Raymond Hettinger5088f602015-12-13 18:45:01 -0800285 entry->key = key;
Raymond Hettinger86d322f2015-12-13 19:27:17 -0800286 entry->hash = hash;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000287}
288
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700289/* ======== End logic for probing the hash table ========================== */
290/* ======================================================================== */
291
Thomas Wouters89f507f2006-12-13 04:49:30 +0000292/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000293Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000294keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000295actually be smaller than the old one.
296*/
297static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000298set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000299{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 Py_ssize_t newsize;
301 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800302 Py_ssize_t oldfill = so->fill;
303 Py_ssize_t oldused = so->used;
Raymond Hettinger5088f602015-12-13 18:45:01 -0800304 Py_ssize_t oldmask = so->mask;
305 size_t newmask;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 int is_oldtable_malloced;
307 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 assert(minused >= 0);
Raymond Hettinger48973002015-07-03 20:00:03 -0700310 minused = (minused > 50000) ? minused * 2 : minused * 4;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100313 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 for (newsize = PySet_MINSIZE;
315 newsize <= minused && newsize > 0;
316 newsize <<= 1)
317 ;
318 if (newsize <= 0) {
319 PyErr_NoMemory();
320 return -1;
321 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 /* Get space for a new table. */
324 oldtable = so->table;
325 assert(oldtable != NULL);
326 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 if (newsize == PySet_MINSIZE) {
329 /* A large table is shrinking, or we can't get any smaller. */
330 newtable = so->smalltable;
331 if (newtable == oldtable) {
332 if (so->fill == so->used) {
333 /* No dummies, so no point doing anything. */
334 return 0;
335 }
336 /* We're not going to resize it, but rebuild the
337 table anyway to purge old dummy entries.
338 Subtle: This is *necessary* if fill==size,
339 as set_lookkey needs at least one virgin slot to
340 terminate failing searches. If fill < size, it's
341 merely desirable, as dummies slow searches. */
342 assert(so->fill > so->used);
343 memcpy(small_copy, oldtable, sizeof(small_copy));
344 oldtable = small_copy;
345 }
346 }
347 else {
348 newtable = PyMem_NEW(setentry, newsize);
349 if (newtable == NULL) {
350 PyErr_NoMemory();
351 return -1;
352 }
353 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 /* Make the set empty, using the new table. */
356 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 memset(newtable, 0, sizeof(setentry) * newsize);
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800358 so->fill = oldused;
359 so->used = oldused;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800360 so->mask = newsize - 1;
361 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 /* Copy the data over; this is refcount-neutral for active entries;
364 dummy entries aren't copied over, of course */
Raymond Hettinger5088f602015-12-13 18:45:01 -0800365 newmask = (size_t)so->mask;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800366 if (oldfill == oldused) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800367 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800368 if (entry->key != NULL) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800369 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800370 }
371 }
372 } else {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800373 for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800374 if (entry->key != NULL && entry->key != dummy) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800375 set_insert_clean(newtable, newmask, entry->key, entry->hash);
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800376 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 }
378 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 if (is_oldtable_malloced)
381 PyMem_DEL(oldtable);
382 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000383}
384
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000385static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700386set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000387{
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700388 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000389
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700390 entry = set_lookkey(so, key, hash);
391 if (entry != NULL)
392 return entry->key != NULL;
393 return -1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000394}
395
396#define DISCARD_NOTFOUND 0
397#define DISCARD_FOUND 1
398
399static int
Raymond Hettinger73799b12015-07-05 16:06:10 -0700400set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800401{
402 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000404
Raymond Hettingerdc28d5a2015-07-05 10:03:20 -0700405 entry = set_lookkey(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 if (entry == NULL)
407 return -1;
Raymond Hettinger8651a502015-05-27 10:37:20 -0700408 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 return DISCARD_NOTFOUND;
410 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800412 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 so->used--;
414 Py_DECREF(old_key);
415 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000416}
417
418static int
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700419set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000420{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200421 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000422
Raymond Hettingerb48d6a62015-07-05 16:27:44 -0700423 if (!PyUnicode_CheckExact(key) ||
424 (hash = ((PyASCIIObject *) key)->hash) == -1) {
425 hash = PyObject_Hash(key);
426 if (hash == -1)
427 return -1;
428 }
429 return set_add_entry(so, key, hash);
430}
431
432static int
433set_contains_key(PySetObject *so, PyObject *key)
434{
435 Py_hash_t hash;
436
437 if (!PyUnicode_CheckExact(key) ||
438 (hash = ((PyASCIIObject *) key)->hash) == -1) {
439 hash = PyObject_Hash(key);
440 if (hash == -1)
441 return -1;
442 }
443 return set_contains_entry(so, key, hash);
444}
445
446static int
447set_discard_key(PySetObject *so, PyObject *key)
448{
449 Py_hash_t hash;
Christian Heimes0ded5b52007-12-10 15:50:56 +0000450
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200452 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 hash = PyObject_Hash(key);
454 if (hash == -1)
455 return -1;
456 }
Raymond Hettinger73799b12015-07-05 16:06:10 -0700457 return set_discard_entry(so, key, hash);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000458}
459
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700460static void
461set_empty_to_minsize(PySetObject *so)
462{
463 memset(so->smalltable, 0, sizeof(so->smalltable));
464 so->fill = 0;
465 so->used = 0;
466 so->mask = PySet_MINSIZE - 1;
467 so->table = so->smalltable;
468 so->hash = -1;
469}
470
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000471static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000472set_clear_internal(PySetObject *so)
473{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800474 setentry *entry;
475 setentry *table = so->table;
476 Py_ssize_t fill = so->fill;
477 Py_ssize_t used = so->used;
478 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000480
Raymond Hettinger583cd032013-09-07 22:06:35 -0700481 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 /* This is delicate. During the process of clearing the set,
485 * decrefs can cause the set to mutate. To avoid fatal confusion
486 * (voice of experience), we have to make the set empty before
487 * clearing the slots, and never refer to anything via so->ref while
488 * clearing.
489 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700491 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000492
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 else if (fill > 0) {
494 /* It's a small table with something that needs to be cleared.
495 * Afraid the only safe way is to copy the set entries into
496 * another small table first.
497 */
498 memcpy(small_copy, table, sizeof(small_copy));
499 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700500 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 }
502 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* Now we can finally clear things. If C had refcounts, we could
505 * assert that the refcount on table is 1 now, i.e. that this function
506 * has unique access to it, so decref side-effects can't alter it.
507 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800508 for (entry = table; used > 0; entry++) {
509 if (entry->key && entry->key != dummy) {
510 used--;
511 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 if (table_is_malloced)
516 PyMem_DEL(table);
517 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000518}
519
520/*
521 * Iterate over a set table. Use like so:
522 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000523 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000524 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000525 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000526 * while (set_next(yourset, &pos, &entry)) {
527 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000528 * }
529 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000530 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000532 */
533static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000534set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 Py_ssize_t i;
537 Py_ssize_t mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700538 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 assert (PyAnySet_Check(so));
541 i = *pos_ptr;
542 assert(i >= 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 mask = so->mask;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700544 entry = &so->table[i];
545 while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 i++;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700547 entry++;
548 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 *pos_ptr = i+1;
550 if (i > mask)
551 return 0;
Raymond Hettingeref6bd7d2015-07-06 08:43:37 -0700552 assert(entry != NULL);
553 *entry_ptr = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000555}
556
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000557static void
558set_dealloc(PySetObject *so)
559{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200560 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800561 Py_ssize_t used = so->used;
562
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 PyObject_GC_UnTrack(so);
564 Py_TRASHCAN_SAFE_BEGIN(so)
565 if (so->weakreflist != NULL)
566 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000567
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800568 for (entry = so->table; used > 0; entry++) {
569 if (entry->key && entry->key != dummy) {
570 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700571 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 }
573 }
574 if (so->table != so->smalltable)
575 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700576 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000578}
579
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000580static PyObject *
581set_repr(PySetObject *so)
582{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200583 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000585
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 if (status != 0) {
587 if (status < 0)
588 return NULL;
589 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
590 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000591
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 /* shortcut for the empty set */
593 if (!so->used) {
594 Py_ReprLeave((PyObject*)so);
595 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
596 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000597
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 keys = PySequence_List((PyObject *)so);
599 if (keys == NULL)
600 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000601
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200602 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 listrepr = PyObject_Repr(keys);
604 Py_DECREF(keys);
605 if (listrepr == NULL)
606 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200607 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200609 if (tmp == NULL)
610 goto done;
611 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200612
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200613 if (Py_TYPE(so) != &PySet_Type)
614 result = PyUnicode_FromFormat("%s({%U})",
615 Py_TYPE(so)->tp_name,
616 listrepr);
617 else
618 result = PyUnicode_FromFormat("{%U}", listrepr);
619 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000620done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 Py_ReprLeave((PyObject*)so);
622 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000623}
624
Martin v. Löwis18e16552006-02-15 17:27:45 +0000625static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000626set_len(PyObject *so)
627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000629}
630
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000631static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000632set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000633{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000635 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200636 Py_ssize_t i;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700637 setentry *so_entry;
638 setentry *other_entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 assert (PyAnySet_Check(so));
641 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 other = (PySetObject*)otherset;
644 if (other == so || other->used == 0)
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700645 /* a.update(a) or a.update(set()); nothing to do */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000646 return 0;
647 /* Do one big resize at the start, rather than
648 * incrementally resizing as we insert new keys. Expect
649 * that there will be no (or few) overlapping keys.
650 */
Raymond Hettinger15f08692015-07-03 17:21:17 -0700651 if ((so->fill + other->used)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700652 if (set_table_resize(so, so->used + other->used) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000653 return -1;
654 }
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700655 so_entry = so->table;
656 other_entry = other->table;
657
658 /* If our table is empty, and both tables have the same size, and
659 there are no dummies to eliminate, then just copy the pointers. */
660 if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
661 for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
662 key = other_entry->key;
663 if (key != NULL) {
664 assert(so_entry->key == NULL);
665 Py_INCREF(key);
666 so_entry->key = key;
667 so_entry->hash = other_entry->hash;
668 }
669 }
670 so->fill = other->fill;
671 so->used = other->used;
672 return 0;
673 }
674
675 /* If our table is empty, we can use set_insert_clean() */
676 if (so->fill == 0) {
Raymond Hettinger5088f602015-12-13 18:45:01 -0800677 setentry *newtable = so->table;
678 size_t newmask = (size_t)so->mask;
Raymond Hettinger6019c8c2015-11-17 08:28:07 -0800679 so->fill = other->used;
680 so->used = other->used;
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700681 for (i = 0; i <= other->mask; i++, other_entry++) {
682 key = other_entry->key;
683 if (key != NULL && key != dummy) {
684 Py_INCREF(key);
Raymond Hettinger5088f602015-12-13 18:45:01 -0800685 set_insert_clean(newtable, newmask, key, other_entry->hash);
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700686 }
687 }
688 return 0;
689 }
690
691 /* We can't assure there are no duplicates, so do normal insertions */
Raymond Hettingera3626bc2015-07-15 23:50:14 -0700692 for (i = 0; i <= other->mask; i++) {
693 other_entry = &other->table[i];
Raymond Hettinger1bd8d752015-05-13 01:26:14 -0700694 key = other_entry->key;
695 if (key != NULL && key != dummy) {
Raymond Hettinger73799b12015-07-05 16:06:10 -0700696 if (set_add_entry(so, key, other_entry->hash))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 }
699 }
700 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000701}
702
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000703static PyObject *
704set_pop(PySetObject *so)
705{
Raymond Hettinger9cd6a782015-01-18 16:06:18 -0800706 /* Make sure the search finger is in bounds */
707 Py_ssize_t i = so->finger & so->mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200708 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000709 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000710
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000711 assert (PyAnySet_Check(so));
712 if (so->used == 0) {
713 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
714 return NULL;
715 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000716
Raymond Hettinger1202a472015-01-18 13:12:42 -0800717 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
718 i++;
Raymond Hettingered741d42015-01-18 21:25:15 -0800719 if (i > so->mask)
720 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 }
722 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 entry->key = dummy;
Raymond Hettingerb335dfe2015-01-25 16:38:52 -0800724 entry->hash = -1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800726 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000728}
729
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000730PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
731Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000732
733static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000734set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000735{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 Py_ssize_t pos = 0;
737 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000738
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 while (set_next(so, &pos, &entry))
740 Py_VISIT(entry->key);
741 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000742}
743
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700744/* Work to increase the bit dispersion for closely spaced hash values.
745 This is important because some use cases have many combinations of a
746 small number of elements with nearby hashes so that many distinct
747 combinations collapse to only a handful of distinct hash values. */
748
749static Py_uhash_t
750_shuffle_bits(Py_uhash_t h)
751{
752 return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
753}
754
755/* Most of the constants in this hash algorithm are randomly chosen
756 large primes with "interesting bit patterns" and that passed tests
757 for good collision statistics on a variety of problematic datasets
758 including powersets and graph structures (such as David Eppstein's
759 graph recipes in Lib/test/test_set.py) */
760
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000761static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000762frozenset_hash(PyObject *self)
763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 PySetObject *so = (PySetObject *)self;
Raymond Hettinger41481952015-08-07 00:43:39 -0700765 Py_uhash_t hash = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000767
Raymond Hettingerb501a272015-08-06 22:15:22 -0700768 if (so->hash != -1)
769 return so->hash;
770
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700771 /* Xor-in shuffled bits from every entry's hash field because xor is
772 commutative and a frozenset hash should be independent of order.
773
774 For speed, include null entries and dummy entries and then
775 subtract out their effect afterwards so that the final hash
776 depends only on active entries. This allows the code to be
777 vectorized by the compiler and it saves the unpredictable
778 branches that would arise when trying to exclude null and dummy
779 entries on every iteration. */
780
781 for (entry = so->table; entry <= &so->table[so->mask]; entry++)
782 hash ^= _shuffle_bits(entry->hash);
783
Raymond Hettingera286a512015-08-01 11:07:11 -0700784 /* Remove the effect of an odd number of NULL entries */
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700785 if ((so->mask + 1 - so->fill) & 1)
786 hash ^= _shuffle_bits(0);
787
788 /* Remove the effect of an odd number of dummy entries */
789 if ((so->fill - so->used) & 1)
790 hash ^= _shuffle_bits(-1);
791
Raymond Hettinger41481952015-08-07 00:43:39 -0700792 /* Factor in the number of active entries */
793 hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
794
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700795 /* Disperse patterns arising in nested frozensets */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800796 hash = hash * 69069U + 907133923UL;
Raymond Hettingerfbffdef2015-08-01 09:53:00 -0700797
Raymond Hettinger36c05002015-08-01 10:57:42 -0700798 /* -1 is reserved as an error code */
Victor Stinner12174a52014-08-15 23:17:38 +0200799 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800800 hash = 590923713UL;
Raymond Hettinger36c05002015-08-01 10:57:42 -0700801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 so->hash = hash;
803 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000804}
805
Raymond Hettingera9d99362005-08-05 00:01:15 +0000806/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000807
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000808typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 PyObject_HEAD
810 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
811 Py_ssize_t si_used;
Raymond Hettinger9632a7d2015-07-07 15:29:24 -0700812 Py_ssize_t si_pos;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000814} setiterobject;
815
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000816static void
817setiter_dealloc(setiterobject *si)
818{
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 *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000831setiter_len(setiterobject *si)
832{
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 *
844setiter_reduce(setiterobject *si)
845{
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:
922 Py_DECREF(so);
923 si->si_set = NULL;
924 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;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 Py_ssize_t dictsize = PyDict_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 Hettinger15f08692015-07-03 17:21:17 -0700995 if ((so->fill + dictsize)*3 >= so->mask*2) {
Raymond Hettinger48973002015-07-03 20:00:03 -0700996 if (set_table_resize(so, so->used + dictsize) != 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{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +02001049 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +00001050
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001052 so = (PySetObject *)type->tp_alloc(type, 0);
1053 if (so == NULL)
1054 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001055
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001056 so->fill = 0;
1057 so->used = 0;
1058 so->mask = PySet_MINSIZE - 1;
1059 so->table = so->smalltable;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001060 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001061 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 if (iterable != NULL) {
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001065 if (set_update_internal(so, iterable)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 Py_DECREF(so);
1067 return NULL;
1068 }
1069 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001072}
1073
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001074static PyObject *
1075make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1078 if (PyType_IsSubtype(type, &PySet_Type))
1079 type = &PySet_Type;
1080 else
1081 type = &PyFrozenSet_Type;
1082 }
1083 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001084}
1085
Raymond Hettingerd7946662005-08-01 21:39:29 +00001086/* The empty frozenset is a singleton */
1087static PyObject *emptyfrozenset = NULL;
1088
Raymond Hettingera690a992003-11-16 16:17:49 +00001089static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001090frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001091{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1095 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001096
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1098 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (type != &PyFrozenSet_Type)
1101 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 if (iterable != NULL) {
1104 /* frozenset(f) is idempotent */
1105 if (PyFrozenSet_CheckExact(iterable)) {
1106 Py_INCREF(iterable);
1107 return iterable;
1108 }
1109 result = make_new_set(type, iterable);
1110 if (result == NULL || PySet_GET_SIZE(result))
1111 return result;
1112 Py_DECREF(result);
1113 }
1114 /* The empty frozenset is a singleton */
1115 if (emptyfrozenset == NULL)
1116 emptyfrozenset = make_new_set(type, NULL);
1117 Py_XINCREF(emptyfrozenset);
1118 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001119}
1120
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001121int
1122PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001123{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001124 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001125}
1126
1127void
1128PySet_Fini(void)
1129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001131}
1132
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001133static PyObject *
1134set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1137 return NULL;
1138
1139 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001140}
1141
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001142/* set_swap_bodies() switches the contents of any two sets by moving their
1143 internal data pointers and, if needed, copying the internal smalltables.
1144 Semantically equivalent to:
1145
1146 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1147
1148 The function always succeeds and it leaves both objects in a stable state.
Raymond Hettinger4d45c102015-01-25 16:27:40 -08001149 Useful for operations that update in-place (by allowing an intermediate
1150 result to be swapped into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001151*/
1152
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001153static void
1154set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 Py_ssize_t t;
1157 setentry *u;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001159 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 t = a->fill; a->fill = b->fill; b->fill = t;
1162 t = a->used; a->used = b->used; b->used = t;
1163 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 u = a->table;
1166 if (a->table == a->smalltable)
1167 u = b->smalltable;
1168 a->table = b->table;
1169 if (b->table == b->smalltable)
1170 a->table = a->smalltable;
1171 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 if (a->table == a->smalltable || b->table == b->smalltable) {
1174 memcpy(tab, a->smalltable, sizeof(tab));
1175 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1176 memcpy(b->smalltable, tab, sizeof(tab));
1177 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1180 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1181 h = a->hash; a->hash = b->hash; b->hash = h;
1182 } else {
1183 a->hash = -1;
1184 b->hash = -1;
1185 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001186}
1187
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001188static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001189set_copy(PySetObject *so)
1190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001192}
1193
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001194static PyObject *
1195frozenset_copy(PySetObject *so)
1196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 if (PyFrozenSet_CheckExact(so)) {
1198 Py_INCREF(so);
1199 return (PyObject *)so;
1200 }
1201 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001202}
1203
Raymond Hettingera690a992003-11-16 16:17:49 +00001204PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1205
1206static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001207set_clear(PySetObject *so)
1208{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 set_clear_internal(so);
1210 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001211}
1212
1213PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1214
1215static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001216set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001217{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 PySetObject *result;
1219 PyObject *other;
1220 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 result = (PySetObject *)set_copy(so);
1223 if (result == NULL)
1224 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1227 other = PyTuple_GET_ITEM(args, i);
1228 if ((PyObject *)so == other)
1229 continue;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001230 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 Py_DECREF(result);
1232 return NULL;
1233 }
1234 }
1235 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001236}
1237
1238PyDoc_STRVAR(union_doc,
1239 "Return the union of sets as a new set.\n\
1240\n\
1241(i.e. all elements that are in either set.)");
1242
1243static PyObject *
1244set_or(PySetObject *so, PyObject *other)
1245{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001247
Brian Curtindfc80e32011-08-10 20:28:54 -05001248 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1249 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001250
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 result = (PySetObject *)set_copy(so);
1252 if (result == NULL)
1253 return NULL;
1254 if ((PyObject *)so == other)
1255 return (PyObject *)result;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001256 if (set_update_internal(result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 Py_DECREF(result);
1258 return NULL;
1259 }
1260 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001261}
1262
Raymond Hettingera690a992003-11-16 16:17:49 +00001263static PyObject *
1264set_ior(PySetObject *so, PyObject *other)
1265{
Brian Curtindfc80e32011-08-10 20:28:54 -05001266 if (!PyAnySet_Check(other))
1267 Py_RETURN_NOTIMPLEMENTED;
1268
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001269 if (set_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001270 return NULL;
1271 Py_INCREF(so);
1272 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001273}
1274
1275static PyObject *
1276set_intersection(PySetObject *so, PyObject *other)
1277{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 PySetObject *result;
1279 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001280 Py_hash_t hash;
1281 int rv;
Raymond Hettingera690a992003-11-16 16:17:49 +00001282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if ((PyObject *)so == other)
1284 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1287 if (result == NULL)
1288 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001289
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 if (PyAnySet_Check(other)) {
1291 Py_ssize_t pos = 0;
1292 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1295 tmp = (PyObject *)so;
1296 so = (PySetObject *)other;
1297 other = tmp;
1298 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001301 key = entry->key;
1302 hash = entry->hash;
1303 rv = set_contains_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001304 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 Py_DECREF(result);
1306 return NULL;
1307 }
1308 if (rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001309 if (set_add_entry(result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 Py_DECREF(result);
1311 return NULL;
1312 }
1313 }
1314 }
1315 return (PyObject *)result;
1316 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 it = PyObject_GetIter(other);
1319 if (it == NULL) {
1320 Py_DECREF(result);
1321 return NULL;
1322 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001325 hash = PyObject_Hash(key);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001326 if (hash == -1)
1327 goto error;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001328 rv = set_contains_entry(so, key, hash);
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001329 if (rv < 0)
1330 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 if (rv) {
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001332 if (set_add_entry(result, key, hash))
1333 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 }
1335 Py_DECREF(key);
1336 }
1337 Py_DECREF(it);
1338 if (PyErr_Occurred()) {
1339 Py_DECREF(result);
1340 return NULL;
1341 }
1342 return (PyObject *)result;
Raymond Hettinger11ce8e62015-07-06 19:08:49 -07001343 error:
1344 Py_DECREF(it);
1345 Py_DECREF(result);
1346 Py_DECREF(key);
1347 return NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001348}
1349
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001350static PyObject *
1351set_intersection_multi(PySetObject *so, PyObject *args)
1352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 Py_ssize_t i;
1354 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 if (PyTuple_GET_SIZE(args) == 0)
1357 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 Py_INCREF(so);
1360 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1361 PyObject *other = PyTuple_GET_ITEM(args, i);
1362 PyObject *newresult = set_intersection((PySetObject *)result, other);
1363 if (newresult == NULL) {
1364 Py_DECREF(result);
1365 return NULL;
1366 }
1367 Py_DECREF(result);
1368 result = newresult;
1369 }
1370 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001371}
1372
Raymond Hettingera690a992003-11-16 16:17:49 +00001373PyDoc_STRVAR(intersection_doc,
1374"Return the intersection of two sets as a new set.\n\
1375\n\
1376(i.e. all elements that are in both sets.)");
1377
1378static PyObject *
1379set_intersection_update(PySetObject *so, PyObject *other)
1380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 tmp = set_intersection(so, other);
1384 if (tmp == NULL)
1385 return NULL;
1386 set_swap_bodies(so, (PySetObject *)tmp);
1387 Py_DECREF(tmp);
1388 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001389}
1390
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001391static PyObject *
1392set_intersection_update_multi(PySetObject *so, PyObject *args)
1393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 tmp = set_intersection_multi(so, args);
1397 if (tmp == NULL)
1398 return NULL;
1399 set_swap_bodies(so, (PySetObject *)tmp);
1400 Py_DECREF(tmp);
1401 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001402}
1403
Raymond Hettingera690a992003-11-16 16:17:49 +00001404PyDoc_STRVAR(intersection_update_doc,
1405"Update a set with the intersection of itself and another.");
1406
1407static PyObject *
1408set_and(PySetObject *so, PyObject *other)
1409{
Brian Curtindfc80e32011-08-10 20:28:54 -05001410 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1411 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001413}
1414
1415static PyObject *
1416set_iand(PySetObject *so, PyObject *other)
1417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001419
Brian Curtindfc80e32011-08-10 20:28:54 -05001420 if (!PyAnySet_Check(other))
1421 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 result = set_intersection_update(so, other);
1423 if (result == NULL)
1424 return NULL;
1425 Py_DECREF(result);
1426 Py_INCREF(so);
1427 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001428}
1429
Guido van Rossum58da9312007-11-10 23:39:45 +00001430static PyObject *
1431set_isdisjoint(PySetObject *so, PyObject *other)
1432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001433 PyObject *key, *it, *tmp;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001434 int rv;
Guido van Rossum58da9312007-11-10 23:39:45 +00001435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 if ((PyObject *)so == other) {
1437 if (PySet_GET_SIZE(so) == 0)
1438 Py_RETURN_TRUE;
1439 else
1440 Py_RETURN_FALSE;
1441 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 if (PyAnySet_CheckExact(other)) {
1444 Py_ssize_t pos = 0;
1445 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1448 tmp = (PyObject *)so;
1449 so = (PySetObject *)other;
1450 other = tmp;
1451 }
1452 while (set_next((PySetObject *)other, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001453 rv = set_contains_entry(so, entry->key, entry->hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001454 if (rv < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 return NULL;
1456 if (rv)
1457 Py_RETURN_FALSE;
1458 }
1459 Py_RETURN_TRUE;
1460 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001461
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 it = PyObject_GetIter(other);
1463 if (it == NULL)
1464 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 while ((key = PyIter_Next(it)) != NULL) {
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001467 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 if (hash == -1) {
1470 Py_DECREF(key);
1471 Py_DECREF(it);
1472 return NULL;
1473 }
Raymond Hettinger73799b12015-07-05 16:06:10 -07001474 rv = set_contains_entry(so, key, hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 Py_DECREF(key);
Raymond Hettingerc2480dc2015-07-04 08:46:31 -07001476 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 Py_DECREF(it);
1478 return NULL;
1479 }
1480 if (rv) {
1481 Py_DECREF(it);
1482 Py_RETURN_FALSE;
1483 }
1484 }
1485 Py_DECREF(it);
1486 if (PyErr_Occurred())
1487 return NULL;
1488 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001489}
1490
1491PyDoc_STRVAR(isdisjoint_doc,
1492"Return True if two sets have a null intersection.");
1493
Neal Norwitz6576bd82005-11-13 18:41:28 +00001494static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001495set_difference_update_internal(PySetObject *so, PyObject *other)
1496{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 if ((PyObject *)so == other)
1498 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 if (PyAnySet_Check(other)) {
1501 setentry *entry;
1502 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 while (set_next((PySetObject *)other, &pos, &entry))
Raymond Hettinger73799b12015-07-05 16:06:10 -07001505 if (set_discard_entry(so, entry->key, entry->hash) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 return -1;
1507 } else {
1508 PyObject *key, *it;
1509 it = PyObject_GetIter(other);
1510 if (it == NULL)
1511 return -1;
1512
1513 while ((key = PyIter_Next(it)) != NULL) {
Raymond Hettingerb3223262015-07-03 23:37:16 -07001514 if (set_discard_key(so, key) < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 Py_DECREF(it);
1516 Py_DECREF(key);
1517 return -1;
1518 }
1519 Py_DECREF(key);
1520 }
1521 Py_DECREF(it);
1522 if (PyErr_Occurred())
1523 return -1;
1524 }
Raymond Hettingere186c762015-07-04 11:28:35 -07001525 /* If more than 1/4th are dummies, then resize them away. */
1526 if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 return 0;
Raymond Hettinger48973002015-07-03 20:00:03 -07001528 return set_table_resize(so, so->used);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001529}
1530
Raymond Hettingera690a992003-11-16 16:17:49 +00001531static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001532set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001535
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1537 PyObject *other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001538 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001539 return NULL;
1540 }
1541 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001542}
1543
1544PyDoc_STRVAR(difference_update_doc,
1545"Remove all elements of another set from this set.");
1546
1547static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001548set_copy_and_difference(PySetObject *so, PyObject *other)
1549{
1550 PyObject *result;
1551
1552 result = set_copy(so);
1553 if (result == NULL)
1554 return NULL;
Raymond Hettingerb3223262015-07-03 23:37:16 -07001555 if (set_difference_update_internal((PySetObject *) result, other) == 0)
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001556 return result;
1557 Py_DECREF(result);
1558 return NULL;
1559}
1560
1561static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001562set_difference(PySetObject *so, PyObject *other)
1563{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 PyObject *result;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001565 PyObject *key;
1566 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 setentry *entry;
1568 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001569 int rv;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001572 return set_copy_and_difference(so, other);
1573 }
1574
1575 /* If len(so) much more than len(other), it's more efficient to simply copy
1576 * so and then iterate other looking for common elements. */
1577 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1578 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001579 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001580
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001581 result = make_new_set_basetype(Py_TYPE(so), NULL);
1582 if (result == NULL)
1583 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001584
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 if (PyDict_CheckExact(other)) {
1586 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001587 key = entry->key;
1588 hash = entry->hash;
Raymond Hettinger15f08692015-07-03 17:21:17 -07001589 rv = _PyDict_Contains(other, key, hash);
Serhiy Storchakafa494fd2015-05-30 17:45:22 +03001590 if (rv < 0) {
1591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001595 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001596 Py_DECREF(result);
1597 return NULL;
1598 }
1599 }
1600 }
1601 return result;
1602 }
1603
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001604 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001605 while (set_next(so, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001606 key = entry->key;
1607 hash = entry->hash;
1608 rv = set_contains_entry((PySetObject *)other, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001609 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001610 Py_DECREF(result);
1611 return NULL;
1612 }
1613 if (!rv) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001614 if (set_add_entry((PySetObject *)result, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 Py_DECREF(result);
1616 return NULL;
1617 }
1618 }
1619 }
1620 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001621}
1622
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001623static PyObject *
1624set_difference_multi(PySetObject *so, PyObject *args)
1625{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 Py_ssize_t i;
1627 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if (PyTuple_GET_SIZE(args) == 0)
1630 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 other = PyTuple_GET_ITEM(args, 0);
1633 result = set_difference(so, other);
1634 if (result == NULL)
1635 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1638 other = PyTuple_GET_ITEM(args, i);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001639 if (set_difference_update_internal((PySetObject *)result, other)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 Py_DECREF(result);
1641 return NULL;
1642 }
1643 }
1644 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001645}
1646
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001647PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001648"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001649\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001650(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001651static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001652set_sub(PySetObject *so, PyObject *other)
1653{
Brian Curtindfc80e32011-08-10 20:28:54 -05001654 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1655 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001657}
1658
1659static PyObject *
1660set_isub(PySetObject *so, PyObject *other)
1661{
Brian Curtindfc80e32011-08-10 20:28:54 -05001662 if (!PyAnySet_Check(other))
1663 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettinger5af9e132015-05-13 01:44:36 -07001664 if (set_difference_update_internal(so, other))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 return NULL;
1666 Py_INCREF(so);
1667 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001668}
1669
1670static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001671set_symmetric_difference_update(PySetObject *so, PyObject *other)
1672{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 PySetObject *otherset;
1674 PyObject *key;
1675 Py_ssize_t pos = 0;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001676 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001677 setentry *entry;
Raymond Hettinger73799b12015-07-05 16:06:10 -07001678 int rv;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001679
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001680 if ((PyObject *)so == other)
1681 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001683 if (PyDict_CheckExact(other)) {
1684 PyObject *value;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001685 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001686 Py_INCREF(key);
Raymond Hettinger73799b12015-07-05 16:06:10 -07001687 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001688 if (rv < 0) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001689 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001692 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001693 if (set_add_entry(so, key, hash)) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001694 Py_DECREF(key);
1695 return NULL;
1696 }
1697 }
Georg Brandl2d444492010-09-03 10:52:55 +00001698 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001699 }
1700 Py_RETURN_NONE;
1701 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001702
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001703 if (PyAnySet_Check(other)) {
1704 Py_INCREF(other);
1705 otherset = (PySetObject *)other;
1706 } else {
1707 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1708 if (otherset == NULL)
1709 return NULL;
1710 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001711
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001712 while (set_next(otherset, &pos, &entry)) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001713 key = entry->key;
1714 hash = entry->hash;
1715 rv = set_discard_entry(so, key, hash);
Raymond Hettingerb3223262015-07-03 23:37:16 -07001716 if (rv < 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001717 Py_DECREF(otherset);
1718 return NULL;
1719 }
1720 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger73799b12015-07-05 16:06:10 -07001721 if (set_add_entry(so, key, hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001722 Py_DECREF(otherset);
1723 return NULL;
1724 }
1725 }
1726 }
1727 Py_DECREF(otherset);
1728 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001729}
1730
1731PyDoc_STRVAR(symmetric_difference_update_doc,
1732"Update a set with the symmetric difference of itself and another.");
1733
1734static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001735set_symmetric_difference(PySetObject *so, PyObject *other)
1736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 PyObject *rv;
1738 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1741 if (otherset == NULL)
1742 return NULL;
1743 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1744 if (rv == NULL)
1745 return NULL;
1746 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 *
Raymond Hettingera690a992003-11-16 16:17:49 +00001976set_reduce(PySetObject *so)
1977{
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 *
2002set_sizeof(PySetObject *so)
2003{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00002005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 res = sizeof(PySetObject);
2007 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 if (!PyAnySet_Check(self))
2019 return -1;
2020 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
2021 return -1;
2022 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
2023 return -1;
2024 set_clear_internal(self);
2025 self->hash = -1;
2026 if (iterable == NULL)
2027 return 0;
2028 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00002029}
2030
Raymond Hettingera690a992003-11-16 16:17:49 +00002031static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 set_len, /* sq_length */
2033 0, /* sq_concat */
2034 0, /* sq_repeat */
2035 0, /* sq_item */
2036 0, /* sq_slice */
2037 0, /* sq_ass_item */
2038 0, /* sq_ass_slice */
2039 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00002040};
2041
2042/* set object ********************************************************/
2043
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002044#ifdef Py_DEBUG
2045static PyObject *test_c_api(PySetObject *so);
2046
2047PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
2048All is well if assertions don't fail.");
2049#endif
2050
Raymond Hettingera690a992003-11-16 16:17:49 +00002051static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 {"add", (PyCFunction)set_add, METH_O,
2053 add_doc},
2054 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2055 clear_doc},
2056 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2057 contains_doc},
2058 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2059 copy_doc},
2060 {"discard", (PyCFunction)set_discard, METH_O,
2061 discard_doc},
2062 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2063 difference_doc},
2064 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2065 difference_update_doc},
2066 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2067 intersection_doc},
2068 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2069 intersection_update_doc},
2070 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2071 isdisjoint_doc},
2072 {"issubset", (PyCFunction)set_issubset, METH_O,
2073 issubset_doc},
2074 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2075 issuperset_doc},
2076 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2077 pop_doc},
2078 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2079 reduce_doc},
2080 {"remove", (PyCFunction)set_remove, METH_O,
2081 remove_doc},
2082 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2083 sizeof_doc},
2084 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2085 symmetric_difference_doc},
2086 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2087 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002088#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2090 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002091#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002092 {"union", (PyCFunction)set_union, METH_VARARGS,
2093 union_doc},
2094 {"update", (PyCFunction)set_update, METH_VARARGS,
2095 update_doc},
2096 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002097};
2098
2099static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 0, /*nb_add*/
2101 (binaryfunc)set_sub, /*nb_subtract*/
2102 0, /*nb_multiply*/
2103 0, /*nb_remainder*/
2104 0, /*nb_divmod*/
2105 0, /*nb_power*/
2106 0, /*nb_negative*/
2107 0, /*nb_positive*/
2108 0, /*nb_absolute*/
2109 0, /*nb_bool*/
2110 0, /*nb_invert*/
2111 0, /*nb_lshift*/
2112 0, /*nb_rshift*/
2113 (binaryfunc)set_and, /*nb_and*/
2114 (binaryfunc)set_xor, /*nb_xor*/
2115 (binaryfunc)set_or, /*nb_or*/
2116 0, /*nb_int*/
2117 0, /*nb_reserved*/
2118 0, /*nb_float*/
2119 0, /*nb_inplace_add*/
2120 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2121 0, /*nb_inplace_multiply*/
2122 0, /*nb_inplace_remainder*/
2123 0, /*nb_inplace_power*/
2124 0, /*nb_inplace_lshift*/
2125 0, /*nb_inplace_rshift*/
2126 (binaryfunc)set_iand, /*nb_inplace_and*/
2127 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2128 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002129};
2130
2131PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002132"set() -> new empty set object\n\
2133set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002134\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002135Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002136
2137PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2139 "set", /* tp_name */
2140 sizeof(PySetObject), /* tp_basicsize */
2141 0, /* tp_itemsize */
2142 /* methods */
2143 (destructor)set_dealloc, /* tp_dealloc */
2144 0, /* tp_print */
2145 0, /* tp_getattr */
2146 0, /* tp_setattr */
2147 0, /* tp_reserved */
2148 (reprfunc)set_repr, /* tp_repr */
2149 &set_as_number, /* tp_as_number */
2150 &set_as_sequence, /* tp_as_sequence */
2151 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002152 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002153 0, /* tp_call */
2154 0, /* tp_str */
2155 PyObject_GenericGetAttr, /* tp_getattro */
2156 0, /* tp_setattro */
2157 0, /* tp_as_buffer */
2158 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2159 Py_TPFLAGS_BASETYPE, /* tp_flags */
2160 set_doc, /* tp_doc */
2161 (traverseproc)set_traverse, /* tp_traverse */
2162 (inquiry)set_clear_internal, /* tp_clear */
2163 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002164 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2165 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 0, /* tp_iternext */
2167 set_methods, /* tp_methods */
2168 0, /* tp_members */
2169 0, /* tp_getset */
2170 0, /* tp_base */
2171 0, /* tp_dict */
2172 0, /* tp_descr_get */
2173 0, /* tp_descr_set */
2174 0, /* tp_dictoffset */
2175 (initproc)set_init, /* tp_init */
2176 PyType_GenericAlloc, /* tp_alloc */
2177 set_new, /* tp_new */
2178 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002179};
2180
2181/* frozenset object ********************************************************/
2182
2183
2184static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2186 contains_doc},
2187 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2188 copy_doc},
2189 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2190 difference_doc},
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002191 {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 intersection_doc},
2193 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2194 isdisjoint_doc},
2195 {"issubset", (PyCFunction)set_issubset, METH_O,
2196 issubset_doc},
2197 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2198 issuperset_doc},
2199 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2200 reduce_doc},
2201 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2202 sizeof_doc},
2203 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2204 symmetric_difference_doc},
2205 {"union", (PyCFunction)set_union, METH_VARARGS,
2206 union_doc},
2207 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002208};
2209
2210static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002211 0, /*nb_add*/
2212 (binaryfunc)set_sub, /*nb_subtract*/
2213 0, /*nb_multiply*/
2214 0, /*nb_remainder*/
2215 0, /*nb_divmod*/
2216 0, /*nb_power*/
2217 0, /*nb_negative*/
2218 0, /*nb_positive*/
2219 0, /*nb_absolute*/
2220 0, /*nb_bool*/
2221 0, /*nb_invert*/
2222 0, /*nb_lshift*/
2223 0, /*nb_rshift*/
2224 (binaryfunc)set_and, /*nb_and*/
2225 (binaryfunc)set_xor, /*nb_xor*/
2226 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002227};
2228
2229PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002230"frozenset() -> empty frozenset object\n\
2231frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002232\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002233Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002234
2235PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002236 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2237 "frozenset", /* tp_name */
2238 sizeof(PySetObject), /* tp_basicsize */
2239 0, /* tp_itemsize */
2240 /* methods */
2241 (destructor)set_dealloc, /* tp_dealloc */
2242 0, /* tp_print */
2243 0, /* tp_getattr */
2244 0, /* tp_setattr */
2245 0, /* tp_reserved */
2246 (reprfunc)set_repr, /* tp_repr */
2247 &frozenset_as_number, /* tp_as_number */
2248 &set_as_sequence, /* tp_as_sequence */
2249 0, /* tp_as_mapping */
2250 frozenset_hash, /* tp_hash */
2251 0, /* tp_call */
2252 0, /* tp_str */
2253 PyObject_GenericGetAttr, /* tp_getattro */
2254 0, /* tp_setattro */
2255 0, /* tp_as_buffer */
2256 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2257 Py_TPFLAGS_BASETYPE, /* tp_flags */
2258 frozenset_doc, /* tp_doc */
2259 (traverseproc)set_traverse, /* tp_traverse */
2260 (inquiry)set_clear_internal, /* tp_clear */
2261 (richcmpfunc)set_richcompare, /* tp_richcompare */
Raymond Hettinger5d2385f2015-07-08 11:52:27 -07002262 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002263 (getiterfunc)set_iter, /* tp_iter */
2264 0, /* tp_iternext */
2265 frozenset_methods, /* tp_methods */
2266 0, /* tp_members */
2267 0, /* tp_getset */
2268 0, /* tp_base */
2269 0, /* tp_dict */
2270 0, /* tp_descr_get */
2271 0, /* tp_descr_set */
2272 0, /* tp_dictoffset */
2273 0, /* tp_init */
2274 PyType_GenericAlloc, /* tp_alloc */
2275 frozenset_new, /* tp_new */
2276 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002277};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002278
2279
2280/***** C API functions *************************************************/
2281
2282PyObject *
2283PySet_New(PyObject *iterable)
2284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002286}
2287
2288PyObject *
2289PyFrozenSet_New(PyObject *iterable)
2290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002291 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002292}
2293
Neal Norwitz8c49c822006-03-04 18:41:19 +00002294Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002295PySet_Size(PyObject *anyset)
2296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002297 if (!PyAnySet_Check(anyset)) {
2298 PyErr_BadInternalCall();
2299 return -1;
2300 }
2301 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002302}
2303
2304int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002305PySet_Clear(PyObject *set)
2306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 if (!PySet_Check(set)) {
2308 PyErr_BadInternalCall();
2309 return -1;
2310 }
2311 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002312}
2313
2314int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002315PySet_Contains(PyObject *anyset, PyObject *key)
2316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002317 if (!PyAnySet_Check(anyset)) {
2318 PyErr_BadInternalCall();
2319 return -1;
2320 }
2321 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002322}
2323
2324int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002325PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002326{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002327 if (!PySet_Check(set)) {
2328 PyErr_BadInternalCall();
2329 return -1;
2330 }
2331 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002332}
2333
2334int
Christian Heimesfd66e512008-01-29 12:18:50 +00002335PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002336{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002337 if (!PySet_Check(anyset) &&
2338 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2339 PyErr_BadInternalCall();
2340 return -1;
2341 }
2342 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002343}
2344
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002345int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002346_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002347{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002348 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 if (!PyAnySet_Check(set)) {
2351 PyErr_BadInternalCall();
2352 return -1;
2353 }
2354 if (set_next((PySetObject *)set, pos, &entry) == 0)
2355 return 0;
2356 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002357 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002359}
2360
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002361PyObject *
2362PySet_Pop(PyObject *set)
2363{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 if (!PySet_Check(set)) {
2365 PyErr_BadInternalCall();
2366 return NULL;
2367 }
2368 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002369}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002370
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002371int
2372_PySet_Update(PyObject *set, PyObject *iterable)
2373{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002374 if (!PySet_Check(set)) {
2375 PyErr_BadInternalCall();
2376 return -1;
2377 }
2378 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002379}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002380
Raymond Hettingere259f132013-12-15 11:56:14 -08002381/* Exported for the gdb plugin's benefit. */
2382PyObject *_PySet_Dummy = dummy;
2383
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002384#ifdef Py_DEBUG
2385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002386/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002387 Returns True and original set is restored. */
2388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002389#define assertRaises(call_return_value, exception) \
2390 do { \
2391 assert(call_return_value); \
2392 assert(PyErr_ExceptionMatches(exception)); \
2393 PyErr_Clear(); \
2394 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002395
2396static PyObject *
2397test_c_api(PySetObject *so)
2398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 Py_ssize_t count;
2400 char *s;
2401 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002402 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002404 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002407 /* Verify preconditions */
2408 assert(PyAnySet_Check(ob));
2409 assert(PyAnySet_CheckExact(ob));
2410 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 /* so.clear(); so |= set("abc"); */
2413 str = PyUnicode_FromString("abc");
2414 if (str == NULL)
2415 return NULL;
2416 set_clear_internal(so);
Raymond Hettinger5af9e132015-05-13 01:44:36 -07002417 if (set_update_internal(so, str)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002418 Py_DECREF(str);
2419 return NULL;
2420 }
2421 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* Exercise type/size checks */
2424 assert(PySet_Size(ob) == 3);
2425 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 /* Raise TypeError for non-iterable constructor arguments */
2428 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2429 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 /* Raise TypeError for unhashable key */
2432 dup = PySet_New(ob);
2433 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2434 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2435 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Exercise successful pop, contains, add, and discard */
2438 elem = PySet_Pop(ob);
2439 assert(PySet_Contains(ob, elem) == 0);
2440 assert(PySet_GET_SIZE(ob) == 2);
2441 assert(PySet_Add(ob, elem) == 0);
2442 assert(PySet_Contains(ob, elem) == 1);
2443 assert(PySet_GET_SIZE(ob) == 3);
2444 assert(PySet_Discard(ob, elem) == 1);
2445 assert(PySet_GET_SIZE(ob) == 2);
2446 assert(PySet_Discard(ob, elem) == 0);
2447 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002448
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002449 /* Exercise clear */
2450 dup2 = PySet_New(dup);
2451 assert(PySet_Clear(dup2) == 0);
2452 assert(PySet_Size(dup2) == 0);
2453 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002455 /* Raise SystemError on clear or update of frozen set */
2456 f = PyFrozenSet_New(dup);
2457 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2458 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2459 assert(PySet_Add(f, elem) == 0);
2460 Py_INCREF(f);
2461 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2462 Py_DECREF(f);
2463 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002465 /* Exercise direct iteration */
2466 i = 0, count = 0;
2467 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2468 s = _PyUnicode_AsString(x);
2469 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2470 count++;
2471 }
2472 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002474 /* Exercise updates */
2475 dup2 = PySet_New(NULL);
2476 assert(_PySet_Update(dup2, dup) == 0);
2477 assert(PySet_Size(dup2) == 3);
2478 assert(_PySet_Update(dup2, dup) == 0);
2479 assert(PySet_Size(dup2) == 3);
2480 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002482 /* Raise SystemError when self argument is not a set or frozenset. */
2483 t = PyTuple_New(0);
2484 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2485 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2486 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002488 /* Raise SystemError when self argument is not a set. */
2489 f = PyFrozenSet_New(dup);
2490 assert(PySet_Size(f) == 3);
2491 assert(PyFrozenSet_CheckExact(f));
2492 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2493 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2494 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002496 /* Raise KeyError when popping from an empty set */
2497 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2498 Py_DECREF(ob);
2499 assert(PySet_GET_SIZE(ob) == 0);
2500 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002501
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002502 /* Restore the set from the copy using the PyNumber API */
2503 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2504 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002506 /* Verify constructors accept NULL arguments */
2507 f = PySet_New(NULL);
2508 assert(f != NULL);
2509 assert(PySet_GET_SIZE(f) == 0);
2510 Py_DECREF(f);
2511 f = PyFrozenSet_New(NULL);
2512 assert(f != NULL);
2513 assert(PyFrozenSet_CheckExact(f));
2514 assert(PySet_GET_SIZE(f) == 0);
2515 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002517 Py_DECREF(elem);
2518 Py_DECREF(dup);
2519 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002520}
2521
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002522#undef assertRaises
2523
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002524#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002525
2526/***** Dummy Struct *************************************************/
2527
2528static PyObject *
2529dummy_repr(PyObject *op)
2530{
2531 return PyUnicode_FromString("<dummy key>");
2532}
2533
2534static void
2535dummy_dealloc(PyObject* ignore)
2536{
2537 Py_FatalError("deallocating <dummy key>");
2538}
2539
2540static PyTypeObject _PySetDummy_Type = {
2541 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2542 "<dummy key> type",
2543 0,
2544 0,
2545 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2546 0, /*tp_print*/
2547 0, /*tp_getattr*/
2548 0, /*tp_setattr*/
2549 0, /*tp_reserved*/
2550 dummy_repr, /*tp_repr*/
2551 0, /*tp_as_number*/
2552 0, /*tp_as_sequence*/
2553 0, /*tp_as_mapping*/
2554 0, /*tp_hash */
2555 0, /*tp_call */
2556 0, /*tp_str */
2557 0, /*tp_getattro */
2558 0, /*tp_setattro */
2559 0, /*tp_as_buffer */
2560 Py_TPFLAGS_DEFAULT, /*tp_flags */
2561};
2562
2563static PyObject _dummy_struct = {
2564 _PyObject_EXTRA_INIT
2565 2, &_PySetDummy_Type
2566};
2567