blob: 9dc88c834ef58d814889c374c67c80726f686ffc [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 Hettinger426d9952014-05-18 21:40:20 +01007 Copyright (c) 2003-2014 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
26 Unlike the dictionary implementation, the lookkey functions can return
27 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"
Christian Heimes0ded5b52007-12-10 15:50:56 +000032#include "stringlib/eq.h"
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000033
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000034/* Object used as dummy key to fill deleted entries */
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -050035static PyObject _dummy_struct;
36
37#define dummy (&_dummy_struct)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000038
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000039
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -070040/* ======================================================================== */
41/* ======= Begin logic for probing the hash table ========================= */
42
Raymond Hettinger710a67e2013-09-21 20:17:31 -070043/* Set this to zero to turn-off linear probing */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070044#ifndef LINEAR_PROBES
Raymond Hettinger742d8712013-09-08 00:25:57 -070045#define LINEAR_PROBES 9
Raymond Hettinger8408dc52013-09-15 14:57:15 -070046#endif
Raymond Hettinger742d8712013-09-08 00:25:57 -070047
48/* This must be >= 1 */
49#define PERTURB_SHIFT 5
50
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000051static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020052set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000054 setentry *table = so->table;
Raymond Hettingerafe89092013-08-28 20:59:31 -070055 setentry *freeslot = NULL;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020056 setentry *entry;
Raymond Hettingerafe89092013-08-28 20:59:31 -070057 size_t perturb = hash;
58 size_t mask = so->mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -070059 size_t i = (size_t)hash; /* Unsigned for defined overflow behavior. */
Raymond Hettinger8408dc52013-09-15 14:57:15 -070060 size_t j;
Raymond Hettinger4ef05282013-09-21 15:39:49 -070061 int cmp;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +000062
Raymond Hettingera35adf52013-09-02 03:23:21 -070063 entry = &table[i & mask];
Raymond Hettingerafe89092013-08-28 20:59:31 -070064 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 return entry;
Raymond Hettinger237b34b2013-08-17 02:31:53 -070066
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -070067 while (1) {
Raymond Hettinger426d9952014-05-18 21:40:20 +010068 if (entry->hash == hash && entry->key != dummy) { /* dummy match unlikely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070069 PyObject *startkey = entry->key;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080070 if (startkey == key)
71 return entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 Py_INCREF(startkey);
73 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
74 Py_DECREF(startkey);
Raymond Hettinger426d9952014-05-18 21:40:20 +010075 if (cmp < 0) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 return NULL;
Raymond Hettinger426d9952014-05-18 21:40:20 +010077 if (table != so->table || entry->key != startkey) /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 return set_lookkey(so, key, hash);
Raymond Hettinger426d9952014-05-18 21:40:20 +010079 if (cmp > 0) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -070080 return entry;
81 }
82 if (entry->key == dummy && freeslot == NULL)
83 freeslot = entry;
84
Raymond Hettingerc70a2b72013-09-21 14:02:55 -070085 for (j = 1 ; j <= LINEAR_PROBES ; j++) {
86 entry = &table[(i + j) & mask];
Raymond Hettingera35adf52013-09-02 03:23:21 -070087 if (entry->key == NULL)
88 goto found_null;
Raymond Hettingera35adf52013-09-02 03:23:21 -070089 if (entry->hash == hash && entry->key != dummy) {
90 PyObject *startkey = entry->key;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -080091 if (startkey == key)
92 return entry;
Raymond Hettingera35adf52013-09-02 03:23:21 -070093 Py_INCREF(startkey);
94 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
95 Py_DECREF(startkey);
96 if (cmp < 0)
97 return NULL;
98 if (table != so->table || entry->key != startkey)
99 return set_lookkey(so, key, hash);
100 if (cmp > 0)
101 return entry;
102 }
103 if (entry->key == dummy && freeslot == NULL)
104 freeslot = entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700106
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700107 perturb >>= PERTURB_SHIFT;
Raymond Hettingerc56e0e32013-09-02 16:32:27 -0700108 i = i * 5 + 1 + perturb;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700109
Raymond Hettingera35adf52013-09-02 03:23:21 -0700110 entry = &table[i & mask];
Raymond Hettingerafe89092013-08-28 20:59:31 -0700111 if (entry->key == NULL)
Raymond Hettinger8408dc52013-09-15 14:57:15 -0700112 goto found_null;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700114 found_null:
Raymond Hettingerafe89092013-08-28 20:59:31 -0700115 return freeslot == NULL ? entry : freeslot;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000116}
117
118/*
Christian Heimes0ded5b52007-12-10 15:50:56 +0000119 * Hacked up version of set_lookkey which can assume keys are always unicode;
120 * This means we can always use unicode_eq directly and not have to check to
Raymond Hettinger9bda1d62005-09-16 07:14:21 +0000121 * see if the comparison altered the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000122 */
123static setentry *
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200124set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 setentry *table = so->table;
Raymond Hettingerafe89092013-08-28 20:59:31 -0700127 setentry *freeslot = NULL;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200128 setentry *entry;
Raymond Hettingerafe89092013-08-28 20:59:31 -0700129 size_t perturb = hash;
130 size_t mask = so->mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700131 size_t i = (size_t)hash;
132 size_t j;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000133
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 /* Make sure this function doesn't have to handle non-unicode keys,
135 including subclasses of str; e.g., one reason to subclass
136 strings is to override __eq__, and for speed we don't cater to
137 that here. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100138 if (!PyUnicode_CheckExact(key)) { /* unlikely */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 so->lookup = set_lookkey;
140 return set_lookkey(so, key, hash);
141 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700142
Raymond Hettingera35adf52013-09-02 03:23:21 -0700143 entry = &table[i & mask];
Raymond Hettingerafe89092013-08-28 20:59:31 -0700144 if (entry->key == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 return entry;
Raymond Hettingered6c1ef2005-08-13 08:28:03 +0000146
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700147 while (1) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800148 if (entry->hash == hash
149 && (entry->key == key
150 || (entry->key != dummy /* unlikely */
151 && unicode_eq(entry->key, key)))) /* likely */
Raymond Hettingerafe89092013-08-28 20:59:31 -0700152 return entry;
153 if (entry->key == dummy && freeslot == NULL)
154 freeslot = entry;
155
Raymond Hettingerc70a2b72013-09-21 14:02:55 -0700156 for (j = 1 ; j <= LINEAR_PROBES ; j++) {
157 entry = &table[(i + j) & mask];
Raymond Hettingera35adf52013-09-02 03:23:21 -0700158 if (entry->key == NULL)
159 goto found_null;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800160 if (entry->hash == hash
161 && (entry->key == key
162 || (entry->key != dummy /* unlikely */
163 && unicode_eq(entry->key, key)))) /* likely */
Raymond Hettingera35adf52013-09-02 03:23:21 -0700164 return entry;
165 if (entry->key == dummy && freeslot == NULL)
166 freeslot = entry;
167 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700168
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700169 perturb >>= PERTURB_SHIFT;
Raymond Hettingerc56e0e32013-09-02 16:32:27 -0700170 i = i * 5 + 1 + perturb;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700171
Raymond Hettingera35adf52013-09-02 03:23:21 -0700172 entry = &table[i & mask];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 if (entry->key == NULL)
Raymond Hettinger8408dc52013-09-15 14:57:15 -0700174 goto found_null;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700176 found_null:
Raymond Hettingerafe89092013-08-28 20:59:31 -0700177 return freeslot == NULL ? entry : freeslot;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000178}
179
180/*
Thomas Wouters89f507f2006-12-13 04:49:30 +0000181Internal routine used by set_table_resize() to insert an item which is
182known to be absent from the set. This routine also assumes that
183the set contains no deleted entries. Besides the performance benefit,
184using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209).
185Note that no refcounts are changed by this routine; if needed, the caller
186is responsible for incref'ing `key`.
187*/
188static void
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200189set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 setentry *table = so->table;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200192 setentry *entry;
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700193 size_t perturb = hash;
194 size_t mask = (size_t)so->mask;
Raymond Hettingera35adf52013-09-02 03:23:21 -0700195 size_t i = (size_t)hash;
196 size_t j;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000197
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700198 while (1) {
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800199 for (j = 0 ; j <= LINEAR_PROBES ; j++) {
Raymond Hettingera35adf52013-09-02 03:23:21 -0700200 entry = &table[(i + j) & mask];
201 if (entry->key == NULL)
202 goto found_null;
203 }
Raymond Hettinger3c0a4f52013-08-19 07:36:04 -0700204 perturb >>= PERTURB_SHIFT;
Raymond Hettingerc56e0e32013-09-02 16:32:27 -0700205 i = i * 5 + 1 + perturb;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 }
Raymond Hettingera35adf52013-09-02 03:23:21 -0700207 found_null:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 entry->key = key;
209 entry->hash = hash;
Raymond Hettinger4ef05282013-09-21 15:39:49 -0700210 so->fill++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 so->used++;
Thomas Wouters89f507f2006-12-13 04:49:30 +0000212}
213
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700214/* ======== End logic for probing the hash table ========================== */
215/* ======================================================================== */
216
217
218/*
219Internal routine to insert a new key into the table.
220Used by the public insert routine.
221Eats a reference to key.
222*/
223static int
224set_insert_key(PySetObject *so, PyObject *key, Py_hash_t hash)
225{
226 setentry *entry;
227
228 assert(so->lookup != NULL);
229 entry = so->lookup(so, key, hash);
230 if (entry == NULL)
231 return -1;
232 if (entry->key == NULL) {
233 /* UNUSED */
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700234 entry->key = key;
235 entry->hash = hash;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800236 so->fill++;
Raymond Hettinger04fd9dd2013-09-07 17:41:01 -0700237 so->used++;
238 } else if (entry->key == dummy) {
239 /* DUMMY */
240 entry->key = key;
241 entry->hash = hash;
242 so->used++;
243 } else {
244 /* ACTIVE */
245 Py_DECREF(key);
246 }
247 return 0;
248}
249
Thomas Wouters89f507f2006-12-13 04:49:30 +0000250/*
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000251Restructure the table by allocating a new table and reinserting all
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000252keys again. When entries have been deleted, the new table may
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000253actually be smaller than the old one.
254*/
255static int
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256set_table_resize(PySetObject *so, Py_ssize_t minused)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000257{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 Py_ssize_t newsize;
259 setentry *oldtable, *newtable, *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800260 Py_ssize_t oldfill = so->fill;
261 Py_ssize_t oldused = so->used;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 int is_oldtable_malloced;
263 setentry small_copy[PySet_MINSIZE];
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 assert(minused >= 0);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 /* Find the smallest table size > minused. */
Raymond Hettinger426d9952014-05-18 21:40:20 +0100268 /* XXX speed-up with intrinsics */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 for (newsize = PySet_MINSIZE;
270 newsize <= minused && newsize > 0;
271 newsize <<= 1)
272 ;
273 if (newsize <= 0) {
274 PyErr_NoMemory();
275 return -1;
276 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 /* Get space for a new table. */
279 oldtable = so->table;
280 assert(oldtable != NULL);
281 is_oldtable_malloced = oldtable != so->smalltable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (newsize == PySet_MINSIZE) {
284 /* A large table is shrinking, or we can't get any smaller. */
285 newtable = so->smalltable;
286 if (newtable == oldtable) {
287 if (so->fill == so->used) {
288 /* No dummies, so no point doing anything. */
289 return 0;
290 }
291 /* We're not going to resize it, but rebuild the
292 table anyway to purge old dummy entries.
293 Subtle: This is *necessary* if fill==size,
294 as set_lookkey needs at least one virgin slot to
295 terminate failing searches. If fill < size, it's
296 merely desirable, as dummies slow searches. */
297 assert(so->fill > so->used);
298 memcpy(small_copy, oldtable, sizeof(small_copy));
299 oldtable = small_copy;
300 }
301 }
302 else {
303 newtable = PyMem_NEW(setentry, newsize);
304 if (newtable == NULL) {
305 PyErr_NoMemory();
306 return -1;
307 }
308 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 /* Make the set empty, using the new table. */
311 assert(newtable != oldtable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 memset(newtable, 0, sizeof(setentry) * newsize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 so->fill = 0;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800314 so->used = 0;
315 so->mask = newsize - 1;
316 so->table = newtable;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 /* Copy the data over; this is refcount-neutral for active entries;
319 dummy entries aren't copied over, of course */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800320 if (oldfill == oldused) {
321 for (entry = oldtable; oldused > 0; entry++) {
322 if (entry->key != NULL) {
323 oldused--;
324 set_insert_clean(so, entry->key, entry->hash);
325 }
326 }
327 } else {
328 for (entry = oldtable; oldused > 0; entry++) {
329 if (entry->key != NULL && entry->key != dummy) {
330 oldused--;
331 set_insert_clean(so, entry->key, entry->hash);
332 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 }
334 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 if (is_oldtable_malloced)
337 PyMem_DEL(oldtable);
338 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000339}
340
Raymond Hettingerc991db22005-08-11 07:58:45 +0000341/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */
342
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000343static int
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200344set_add_entry(PySetObject *so, setentry *entry)
Raymond Hettingerc991db22005-08-11 07:58:45 +0000345{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200346 Py_ssize_t n_used;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000347 PyObject *key = entry->key;
Éric Araujobbcfc1f2011-03-23 03:43:22 +0100348 Py_hash_t hash = entry->hash;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 assert(so->fill <= so->mask); /* at least one empty slot */
351 n_used = so->used;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000352 Py_INCREF(key);
Éric Araujo48049912011-03-23 02:08:07 +0100353 if (set_insert_key(so, key, hash) == -1) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000354 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 return -1;
356 }
357 if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
358 return 0;
359 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +0000360}
361
362static int
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200363set_add_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000364{
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800365 setentry entry;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200366 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200369 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 hash = PyObject_Hash(key);
371 if (hash == -1)
372 return -1;
373 }
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800374 entry.key = key;
375 entry.hash = hash;
376 return set_add_entry(so, &entry);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000377}
378
379#define DISCARD_NOTFOUND 0
380#define DISCARD_FOUND 1
381
382static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000383set_discard_entry(PySetObject *so, setentry *oldentry)
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800384{
385 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000386 PyObject *old_key;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000387
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000388 entry = (so->lookup)(so, oldentry->key, oldentry->hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 if (entry == NULL)
390 return -1;
391 if (entry->key == NULL || entry->key == dummy)
392 return DISCARD_NOTFOUND;
393 old_key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 entry->key = dummy;
395 so->used--;
396 Py_DECREF(old_key);
397 return DISCARD_FOUND;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000398}
399
400static int
401set_discard_key(PySetObject *so, PyObject *key)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000402{
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800403 setentry entry;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200404 Py_hash_t hash;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000405
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 assert (PyAnySet_Check(so));
Christian Heimes0ded5b52007-12-10 15:50:56 +0000407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 if (!PyUnicode_CheckExact(key) ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200409 (hash = ((PyASCIIObject *) key)->hash) == -1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 hash = PyObject_Hash(key);
411 if (hash == -1)
412 return -1;
413 }
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800414 entry.key = key;
415 entry.hash = hash;
416 return set_discard_entry(so, &entry);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000417}
418
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700419static void
420set_empty_to_minsize(PySetObject *so)
421{
422 memset(so->smalltable, 0, sizeof(so->smalltable));
423 so->fill = 0;
424 so->used = 0;
425 so->mask = PySet_MINSIZE - 1;
426 so->table = so->smalltable;
427 so->hash = -1;
428}
429
Raymond Hettingerfe889f32005-08-06 05:43:39 +0000430static int
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000431set_clear_internal(PySetObject *so)
432{
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800433 setentry *entry;
434 setentry *table = so->table;
435 Py_ssize_t fill = so->fill;
436 Py_ssize_t used = so->used;
437 int table_is_malloced = table != so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 setentry small_copy[PySet_MINSIZE];
Raymond Hettingera580c472005-08-05 17:19:54 +0000439
Raymond Hettinger583cd032013-09-07 22:06:35 -0700440 assert (PyAnySet_Check(so));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 assert(table != NULL);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 /* This is delicate. During the process of clearing the set,
444 * decrefs can cause the set to mutate. To avoid fatal confusion
445 * (voice of experience), we have to make the set empty before
446 * clearing the slots, and never refer to anything via so->ref while
447 * clearing.
448 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 if (table_is_malloced)
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700450 set_empty_to_minsize(so);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 else if (fill > 0) {
453 /* It's a small table with something that needs to be cleared.
454 * Afraid the only safe way is to copy the set entries into
455 * another small table first.
456 */
457 memcpy(small_copy, table, sizeof(small_copy));
458 table = small_copy;
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700459 set_empty_to_minsize(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 }
461 /* else it's a small table that's already empty */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000462
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 /* Now we can finally clear things. If C had refcounts, we could
464 * assert that the refcount on table is 1 now, i.e. that this function
465 * has unique access to it, so decref side-effects can't alter it.
466 */
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800467 for (entry = table; used > 0; entry++) {
468 if (entry->key && entry->key != dummy) {
469 used--;
470 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (table_is_malloced)
475 PyMem_DEL(table);
476 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000477}
478
479/*
480 * Iterate over a set table. Use like so:
481 *
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000482 * Py_ssize_t pos;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000483 * setentry *entry;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000484 * pos = 0; # important! pos should not otherwise be changed by you
Raymond Hettingerc991db22005-08-11 07:58:45 +0000485 * while (set_next(yourset, &pos, &entry)) {
486 * Refer to borrowed reference in entry->key.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000487 * }
488 *
Raymond Hettingerc991db22005-08-11 07:58:45 +0000489 * CAUTION: In general, it isn't safe to use set_next in a loop that
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 * mutates the table.
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000491 */
492static int
Martin v. Löwis18e16552006-02-15 17:27:45 +0000493set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000494{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 Py_ssize_t i;
496 Py_ssize_t mask;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200497 setentry *table;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000498
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 assert (PyAnySet_Check(so));
500 i = *pos_ptr;
501 assert(i >= 0);
502 table = so->table;
503 mask = so->mask;
504 while (i <= mask && (table[i].key == NULL || table[i].key == dummy))
505 i++;
506 *pos_ptr = i+1;
507 if (i > mask)
508 return 0;
509 assert(table[i].key != NULL);
510 *entry_ptr = &table[i];
511 return 1;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000512}
513
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000514static void
515set_dealloc(PySetObject *so)
516{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200517 setentry *entry;
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800518 Py_ssize_t used = so->used;
519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 PyObject_GC_UnTrack(so);
521 Py_TRASHCAN_SAFE_BEGIN(so)
522 if (so->weakreflist != NULL)
523 PyObject_ClearWeakRefs((PyObject *) so);
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000524
Raymond Hettinger08e3dc02014-12-26 20:14:00 -0800525 for (entry = so->table; used > 0; entry++) {
526 if (entry->key && entry->key != dummy) {
527 used--;
Raymond Hettingerfcf3b502013-08-22 08:20:31 -0700528 Py_DECREF(entry->key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 }
530 }
531 if (so->table != so->smalltable)
532 PyMem_DEL(so->table);
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700533 Py_TYPE(so)->tp_free(so);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 Py_TRASHCAN_SAFE_END(so)
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000535}
536
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000537static PyObject *
538set_repr(PySetObject *so)
539{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200540 PyObject *result=NULL, *keys, *listrepr, *tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 int status = Py_ReprEnter((PyObject*)so);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000542
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 if (status != 0) {
544 if (status < 0)
545 return NULL;
546 return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
547 }
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 /* shortcut for the empty set */
550 if (!so->used) {
551 Py_ReprLeave((PyObject*)so);
552 return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
553 }
Georg Brandlc4996ba2006-08-28 19:37:11 +0000554
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 keys = PySequence_List((PyObject *)so);
556 if (keys == NULL)
557 goto done;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000558
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200559 /* repr(keys)[1:-1] */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 listrepr = PyObject_Repr(keys);
561 Py_DECREF(keys);
562 if (listrepr == NULL)
563 goto done;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200564 tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 Py_DECREF(listrepr);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200566 if (tmp == NULL)
567 goto done;
568 listrepr = tmp;
Victor Stinnera1a807b2011-05-26 14:24:30 +0200569
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200570 if (Py_TYPE(so) != &PySet_Type)
571 result = PyUnicode_FromFormat("%s({%U})",
572 Py_TYPE(so)->tp_name,
573 listrepr);
574 else
575 result = PyUnicode_FromFormat("{%U}", listrepr);
576 Py_DECREF(listrepr);
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000577done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 Py_ReprLeave((PyObject*)so);
579 return result;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000580}
581
Martin v. Löwis18e16552006-02-15 17:27:45 +0000582static Py_ssize_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000583set_len(PyObject *so)
584{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 return ((PySetObject *)so)->used;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000586}
587
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000588static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000589set_merge(PySetObject *so, PyObject *otherset)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000590{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 PySetObject *other;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000592 PyObject *key;
Éric Araujobbcfc1f2011-03-23 03:43:22 +0100593 Py_hash_t hash;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200594 Py_ssize_t i;
595 setentry *entry;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 assert (PyAnySet_Check(so));
598 assert (PyAnySet_Check(otherset));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 other = (PySetObject*)otherset;
601 if (other == so || other->used == 0)
602 /* a.update(a) or a.update({}); nothing to do */
603 return 0;
604 /* Do one big resize at the start, rather than
605 * incrementally resizing as we insert new keys. Expect
606 * that there will be no (or few) overlapping keys.
607 */
608 if ((so->fill + other->used)*3 >= (so->mask+1)*2) {
609 if (set_table_resize(so, (so->used + other->used)*2) != 0)
610 return -1;
611 }
612 for (i = 0; i <= other->mask; i++) {
613 entry = &other->table[i];
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000614 key = entry->key;
Éric Araujo48049912011-03-23 02:08:07 +0100615 hash = entry->hash;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000616 if (key != NULL &&
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -0500617 key != dummy) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000618 Py_INCREF(key);
Éric Araujo48049912011-03-23 02:08:07 +0100619 if (set_insert_key(so, key, hash) == -1) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +0000620 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 return -1;
622 }
623 }
624 }
625 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000626}
627
628static int
Raymond Hettingerc991db22005-08-11 07:58:45 +0000629set_contains_entry(PySetObject *so, setentry *entry)
630{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 PyObject *key;
632 setentry *lu_entry;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000633
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000634 lu_entry = (so->lookup)(so, entry->key, entry->hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 if (lu_entry == NULL)
636 return -1;
637 key = lu_entry->key;
638 return key != NULL && key != dummy;
Raymond Hettingerc991db22005-08-11 07:58:45 +0000639}
640
Raymond Hettinger8edf27c2014-12-26 23:08:58 -0800641static int
642set_contains_key(PySetObject *so, PyObject *key)
643{
644 setentry entry;
645 Py_hash_t hash;
646
647 if (!PyUnicode_CheckExact(key) ||
648 (hash = ((PyASCIIObject *) key)->hash) == -1) {
649 hash = PyObject_Hash(key);
650 if (hash == -1)
651 return -1;
652 }
653 entry.key = key;
654 entry.hash = hash;
655 return set_contains_entry(so, &entry);
656}
657
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000658static PyObject *
659set_pop(PySetObject *so)
660{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200661 Py_ssize_t i = 0;
662 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000663 PyObject *key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000664
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 assert (PyAnySet_Check(so));
666 if (so->used == 0) {
667 PyErr_SetString(PyExc_KeyError, "pop from an empty set");
668 return NULL;
669 }
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000670
Raymond Hettinger1202a472015-01-18 13:12:42 -0800671 i = so->finger;
672 /* This may be a legit search finger, or it may be a once legit
673 * search finger that's out of bounds now (due to wrapping or
674 * resizing). We simply make sure it's in bounds now.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000675 */
Raymond Hettinger1202a472015-01-18 13:12:42 -0800676 if (i > so->mask)
677 i = 0;
678 while ((entry = &so->table[i])->key == NULL || entry->key==dummy) {
679 i++;
680 if (i > so->mask)
681 i = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 }
683 key = entry->key;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 entry->key = dummy;
685 so->used--;
Raymond Hettinger1202a472015-01-18 13:12:42 -0800686 so->finger = i + 1; /* next place to start */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 return key;
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000688}
689
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000690PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
691Raises KeyError if the set is empty.");
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000692
693static int
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000694set_traverse(PySetObject *so, visitproc visit, void *arg)
Raymond Hettingerce8185e2005-08-13 09:28:48 +0000695{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 Py_ssize_t pos = 0;
697 setentry *entry;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000698
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 while (set_next(so, &pos, &entry))
700 Py_VISIT(entry->key);
701 return 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000702}
703
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000704static Py_hash_t
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000705frozenset_hash(PyObject *self)
706{
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800707 /* Most of the constants in this hash algorithm are randomly choosen
708 large primes with "interesting bit patterns" and that passed
709 tests for good collision statistics on a variety of problematic
710 datasets such as:
711
712 ps = []
713 for r in range(21):
714 ps += itertools.combinations(range(20), r)
715 num_distinct_hashes = len({hash(frozenset(s)) for s in ps})
716
717 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 PySetObject *so = (PySetObject *)self;
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800719 Py_uhash_t h, hash = 1927868237UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 setentry *entry;
721 Py_ssize_t pos = 0;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000722
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 if (so->hash != -1)
724 return so->hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000725
Mark Dickinson57e683e2011-09-24 18:18:40 +0100726 hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000727 while (set_next(so, &pos, &entry)) {
728 /* Work to increase the bit dispersion for closely spaced hash
729 values. The is important because some use cases have many
730 combinations of a small number of elements with nearby
731 hashes so that many distinct combinations collapse to only
732 a handful of distinct hash values. */
Antoine Pitroufbb1c612010-10-23 17:37:54 +0000733 h = entry->hash;
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800734 hash ^= ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 }
Raymond Hettinger74fc8c42014-01-05 12:00:31 -0800736 /* Make the final result spread-out in a different pattern
Eric V. Smith6ba56652014-01-14 08:15:03 -0500737 than the algorithm for tuples or other python objects. */
Gregory P. Smithc2176e42012-12-10 18:32:53 -0800738 hash = hash * 69069U + 907133923UL;
Victor Stinner12174a52014-08-15 23:17:38 +0200739 if (hash == (Py_uhash_t)-1)
Gregory P. Smith27cbcd62012-12-10 18:15:46 -0800740 hash = 590923713UL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 so->hash = hash;
742 return hash;
Raymond Hettingerf408ddf2005-08-17 00:27:42 +0000743}
744
Raymond Hettingera9d99362005-08-05 00:01:15 +0000745/***** Set iterator type ***********************************************/
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000746
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000747typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 PyObject_HEAD
749 PySetObject *si_set; /* Set to NULL when iterator is exhausted */
750 Py_ssize_t si_used;
751 Py_ssize_t si_pos;
752 Py_ssize_t len;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000753} setiterobject;
754
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000755static void
756setiter_dealloc(setiterobject *si)
757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 Py_XDECREF(si->si_set);
759 PyObject_GC_Del(si);
Antoine Pitrou7ddda782009-01-01 15:35:33 +0000760}
761
762static int
763setiter_traverse(setiterobject *si, visitproc visit, void *arg)
764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 Py_VISIT(si->si_set);
766 return 0;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000767}
768
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000769static PyObject *
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000770setiter_len(setiterobject *si)
771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 Py_ssize_t len = 0;
773 if (si->si_set != NULL && si->si_used == si->si_set->used)
774 len = si->len;
Antoine Pitrou671b4d92010-08-17 17:55:07 +0000775 return PyLong_FromSsize_t(len);
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000776}
777
Armin Rigof5b3e362006-02-11 21:32:43 +0000778PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000779
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000780static PyObject *setiter_iternext(setiterobject *si);
781
782static PyObject *
783setiter_reduce(setiterobject *si)
784{
785 PyObject *list;
786 setiterobject tmp;
787
788 list = PyList_New(0);
789 if (!list)
790 return NULL;
791
Ezio Melotti0e1af282012-09-28 16:43:40 +0300792 /* copy the iterator state */
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000793 tmp = *si;
794 Py_XINCREF(tmp.si_set);
Ezio Melotti0e1af282012-09-28 16:43:40 +0300795
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000796 /* iterate the temporary into a list */
797 for(;;) {
798 PyObject *element = setiter_iternext(&tmp);
799 if (element) {
800 if (PyList_Append(list, element)) {
801 Py_DECREF(element);
802 Py_DECREF(list);
803 Py_XDECREF(tmp.si_set);
804 return NULL;
805 }
806 Py_DECREF(element);
807 } else
808 break;
809 }
810 Py_XDECREF(tmp.si_set);
811 /* check for error */
812 if (tmp.si_set != NULL) {
813 /* we have an error */
814 Py_DECREF(list);
815 return NULL;
816 }
Antoine Pitroua7013882012-04-05 00:04:20 +0200817 return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000818}
819
820PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
821
Raymond Hettinger6b27cda2005-09-24 21:23:05 +0000822static PyMethodDef setiter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
Kristján Valur Jónsson31668b82012-04-03 10:49:41 +0000824 {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000825 {NULL, NULL} /* sentinel */
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000826};
827
Raymond Hettinger06d8cf82005-07-31 15:36:06 +0000828static PyObject *setiter_iternext(setiterobject *si)
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000829{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 PyObject *key;
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200831 Py_ssize_t i, mask;
832 setentry *entry;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 PySetObject *so = si->si_set;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 if (so == NULL)
836 return NULL;
837 assert (PyAnySet_Check(so));
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 if (si->si_used != so->used) {
840 PyErr_SetString(PyExc_RuntimeError,
841 "Set changed size during iteration");
842 si->si_used = -1; /* Make this state sticky */
843 return NULL;
844 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 i = si->si_pos;
847 assert(i>=0);
848 entry = so->table;
849 mask = so->mask;
850 while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
851 i++;
852 si->si_pos = i+1;
853 if (i > mask)
854 goto fail;
855 si->len--;
856 key = entry[i].key;
857 Py_INCREF(key);
858 return key;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000859
860fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 Py_DECREF(so);
862 si->si_set = NULL;
863 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000864}
865
Christian Heimesa22e8bd2007-11-29 22:35:39 +0000866PyTypeObject PySetIter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 PyVarObject_HEAD_INIT(&PyType_Type, 0)
868 "set_iterator", /* tp_name */
869 sizeof(setiterobject), /* tp_basicsize */
870 0, /* tp_itemsize */
871 /* methods */
872 (destructor)setiter_dealloc, /* tp_dealloc */
873 0, /* tp_print */
874 0, /* tp_getattr */
875 0, /* tp_setattr */
876 0, /* tp_reserved */
877 0, /* tp_repr */
878 0, /* tp_as_number */
879 0, /* tp_as_sequence */
880 0, /* tp_as_mapping */
881 0, /* tp_hash */
882 0, /* tp_call */
883 0, /* tp_str */
884 PyObject_GenericGetAttr, /* tp_getattro */
885 0, /* tp_setattro */
886 0, /* tp_as_buffer */
887 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
888 0, /* tp_doc */
889 (traverseproc)setiter_traverse, /* tp_traverse */
890 0, /* tp_clear */
891 0, /* tp_richcompare */
892 0, /* tp_weaklistoffset */
893 PyObject_SelfIter, /* tp_iter */
894 (iternextfunc)setiter_iternext, /* tp_iternext */
895 setiter_methods, /* tp_methods */
896 0,
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000897};
898
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000899static PyObject *
900set_iter(PySetObject *so)
901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
903 if (si == NULL)
904 return NULL;
905 Py_INCREF(so);
906 si->si_set = so;
907 si->si_used = so->used;
908 si->si_pos = 0;
909 si->len = so->used;
910 _PyObject_GC_TRACK(si);
911 return (PyObject *)si;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000912}
913
Raymond Hettingerd7946662005-08-01 21:39:29 +0000914static int
Raymond Hettingerd7946662005-08-01 21:39:29 +0000915set_update_internal(PySetObject *so, PyObject *other)
Raymond Hettingera690a992003-11-16 16:17:49 +0000916{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 PyObject *key, *it;
Raymond Hettingera690a992003-11-16 16:17:49 +0000918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 if (PyAnySet_Check(other))
920 return set_merge(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +0000921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 if (PyDict_CheckExact(other)) {
923 PyObject *value;
924 Py_ssize_t pos = 0;
Benjamin Peterson8f67d082010-10-17 20:54:53 +0000925 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 Py_ssize_t dictsize = PyDict_Size(other);
Thomas Wouterscf297e42007-02-23 15:07:44 +0000927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 /* Do one big resize at the start, rather than
929 * incrementally resizing as we insert new keys. Expect
930 * that there will be no (or few) overlapping keys.
931 */
932 if (dictsize == -1)
933 return -1;
934 if ((so->fill + dictsize)*3 >= (so->mask+1)*2) {
935 if (set_table_resize(so, (so->used + dictsize)*2) != 0)
936 return -1;
937 }
938 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
939 setentry an_entry;
Thomas Wouterscf297e42007-02-23 15:07:44 +0000940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 an_entry.hash = hash;
942 an_entry.key = key;
943 if (set_add_entry(so, &an_entry) == -1)
944 return -1;
945 }
946 return 0;
947 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 it = PyObject_GetIter(other);
950 if (it == NULL)
951 return -1;
Raymond Hettingera690a992003-11-16 16:17:49 +0000952
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 while ((key = PyIter_Next(it)) != NULL) {
954 if (set_add_key(so, key) == -1) {
955 Py_DECREF(it);
956 Py_DECREF(key);
957 return -1;
958 }
959 Py_DECREF(key);
960 }
961 Py_DECREF(it);
962 if (PyErr_Occurred())
963 return -1;
964 return 0;
Raymond Hettingerd7946662005-08-01 21:39:29 +0000965}
966
967static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000968set_update(PySetObject *so, PyObject *args)
Raymond Hettingerd7946662005-08-01 21:39:29 +0000969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
973 PyObject *other = PyTuple_GET_ITEM(args, i);
974 if (set_update_internal(so, other) == -1)
975 return NULL;
976 }
977 Py_RETURN_NONE;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000978}
979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980PyDoc_STRVAR(update_doc,
Georg Brandlc28e1fa2008-06-10 19:20:26 +0000981"Update a set with the union of itself and others.");
Raymond Hettingera38123e2003-11-24 22:18:49 +0000982
Raymond Hettinger426d9952014-05-18 21:40:20 +0100983/* XXX Todo:
984 If aligned memory allocations become available, make the
985 set object 64 byte aligned so that most of the fields
986 can be retrieved or updated in a single cache line.
987*/
988
Raymond Hettingera38123e2003-11-24 22:18:49 +0000989static PyObject *
990make_new_set(PyTypeObject *type, PyObject *iterable)
991{
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200992 PySetObject *so = NULL;
Raymond Hettingera38123e2003-11-24 22:18:49 +0000993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 /* create PySetObject structure */
Raymond Hettinger8f8839e2013-09-07 20:26:50 -0700995 so = (PySetObject *)type->tp_alloc(type, 0);
996 if (so == NULL)
997 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +0000998
Raymond Hettinger4ea90802013-09-07 21:01:29 -0700999 so->fill = 0;
1000 so->used = 0;
1001 so->mask = PySet_MINSIZE - 1;
1002 so->table = so->smalltable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 so->lookup = set_lookkey_unicode;
Raymond Hettinger4ea90802013-09-07 21:01:29 -07001004 so->hash = -1;
Raymond Hettinger1202a472015-01-18 13:12:42 -08001005 so->finger = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 so->weakreflist = NULL;
Raymond Hettingera690a992003-11-16 16:17:49 +00001007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 if (iterable != NULL) {
1009 if (set_update_internal(so, iterable) == -1) {
1010 Py_DECREF(so);
1011 return NULL;
1012 }
1013 }
Raymond Hettingera38123e2003-11-24 22:18:49 +00001014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001016}
1017
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001018static PyObject *
1019make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
1020{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 if (type != &PySet_Type && type != &PyFrozenSet_Type) {
1022 if (PyType_IsSubtype(type, &PySet_Type))
1023 type = &PySet_Type;
1024 else
1025 type = &PyFrozenSet_Type;
1026 }
1027 return make_new_set(type, iterable);
Raymond Hettinger7d99f092008-11-16 11:44:54 +00001028}
1029
Raymond Hettingerd7946662005-08-01 21:39:29 +00001030/* The empty frozenset is a singleton */
1031static PyObject *emptyfrozenset = NULL;
1032
Raymond Hettingera690a992003-11-16 16:17:49 +00001033static PyObject *
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001034frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Raymond Hettingera690a992003-11-16 16:17:49 +00001035{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 PyObject *iterable = NULL, *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001037
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 if (type == &PyFrozenSet_Type && !_PyArg_NoKeywords("frozenset()", kwds))
1039 return NULL;
Georg Brandl02c42872005-08-26 06:42:30 +00001040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable))
1042 return NULL;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 if (type != &PyFrozenSet_Type)
1045 return make_new_set(type, iterable);
Raymond Hettingerd7946662005-08-01 21:39:29 +00001046
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 if (iterable != NULL) {
1048 /* frozenset(f) is idempotent */
1049 if (PyFrozenSet_CheckExact(iterable)) {
1050 Py_INCREF(iterable);
1051 return iterable;
1052 }
1053 result = make_new_set(type, iterable);
1054 if (result == NULL || PySet_GET_SIZE(result))
1055 return result;
1056 Py_DECREF(result);
1057 }
1058 /* The empty frozenset is a singleton */
1059 if (emptyfrozenset == NULL)
1060 emptyfrozenset = make_new_set(type, NULL);
1061 Py_XINCREF(emptyfrozenset);
1062 return emptyfrozenset;
Raymond Hettingerd7946662005-08-01 21:39:29 +00001063}
1064
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001065int
1066PySet_ClearFreeList(void)
Raymond Hettingerd7946662005-08-01 21:39:29 +00001067{
Raymond Hettinger8f8839e2013-09-07 20:26:50 -07001068 return 0;
Antoine Pitrou093ce9c2011-12-16 11:24:27 +01001069}
1070
1071void
1072PySet_Fini(void)
1073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 Py_CLEAR(emptyfrozenset);
Raymond Hettingera690a992003-11-16 16:17:49 +00001075}
1076
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001077static PyObject *
1078set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 if (type == &PySet_Type && !_PyArg_NoKeywords("set()", kwds))
1081 return NULL;
1082
1083 return make_new_set(type, NULL);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001084}
1085
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001086/* set_swap_bodies() switches the contents of any two sets by moving their
1087 internal data pointers and, if needed, copying the internal smalltables.
1088 Semantically equivalent to:
1089
1090 t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
1091
1092 The function always succeeds and it leaves both objects in a stable state.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 Useful for creating temporary frozensets from sets for membership testing
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001094 in __contains__(), discard(), and remove(). Also useful for operations
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 that update in-place (by allowing an intermediate result to be swapped
Raymond Hettinger9dcb17c2005-07-31 13:09:28 +00001096 into one of the original inputs).
Raymond Hettinger934d63e2005-07-31 01:33:10 +00001097*/
1098
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001099static void
1100set_swap_bodies(PySetObject *a, PySetObject *b)
Raymond Hettingera690a992003-11-16 16:17:49 +00001101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 Py_ssize_t t;
1103 setentry *u;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001104 setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 setentry tab[PySet_MINSIZE];
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001106 Py_hash_t h;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001107
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 t = a->fill; a->fill = b->fill; b->fill = t;
1109 t = a->used; a->used = b->used; b->used = t;
1110 t = a->mask; a->mask = b->mask; b->mask = t;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001111
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 u = a->table;
1113 if (a->table == a->smalltable)
1114 u = b->smalltable;
1115 a->table = b->table;
1116 if (b->table == b->smalltable)
1117 a->table = a->smalltable;
1118 b->table = u;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001119
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 f = a->lookup; a->lookup = b->lookup; b->lookup = f;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 if (a->table == a->smalltable || b->table == b->smalltable) {
1123 memcpy(tab, a->smalltable, sizeof(tab));
1124 memcpy(a->smalltable, b->smalltable, sizeof(tab));
1125 memcpy(b->smalltable, tab, sizeof(tab));
1126 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type) &&
1129 PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
1130 h = a->hash; a->hash = b->hash; b->hash = h;
1131 } else {
1132 a->hash = -1;
1133 b->hash = -1;
1134 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001135}
1136
Raymond Hettinger8f5cdaa2003-12-13 11:26:12 +00001137static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001138set_copy(PySetObject *so)
1139{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001141}
1142
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001143static PyObject *
1144frozenset_copy(PySetObject *so)
1145{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 if (PyFrozenSet_CheckExact(so)) {
1147 Py_INCREF(so);
1148 return (PyObject *)so;
1149 }
1150 return set_copy(so);
Raymond Hettinger49ba4c32003-11-23 02:49:05 +00001151}
1152
Raymond Hettingera690a992003-11-16 16:17:49 +00001153PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
1154
1155static PyObject *
Raymond Hettingerc991db22005-08-11 07:58:45 +00001156set_clear(PySetObject *so)
1157{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 set_clear_internal(so);
1159 Py_RETURN_NONE;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001160}
1161
1162PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
1163
1164static PyObject *
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001165set_union(PySetObject *so, PyObject *args)
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001166{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 PySetObject *result;
1168 PyObject *other;
1169 Py_ssize_t i;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 result = (PySetObject *)set_copy(so);
1172 if (result == NULL)
1173 return NULL;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1176 other = PyTuple_GET_ITEM(args, i);
1177 if ((PyObject *)so == other)
1178 continue;
1179 if (set_update_internal(result, other) == -1) {
1180 Py_DECREF(result);
1181 return NULL;
1182 }
1183 }
1184 return (PyObject *)result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001185}
1186
1187PyDoc_STRVAR(union_doc,
1188 "Return the union of sets as a new set.\n\
1189\n\
1190(i.e. all elements that are in either set.)");
1191
1192static PyObject *
1193set_or(PySetObject *so, PyObject *other)
1194{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 PySetObject *result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001196
Brian Curtindfc80e32011-08-10 20:28:54 -05001197 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1198 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 result = (PySetObject *)set_copy(so);
1201 if (result == NULL)
1202 return NULL;
1203 if ((PyObject *)so == other)
1204 return (PyObject *)result;
1205 if (set_update_internal(result, other) == -1) {
1206 Py_DECREF(result);
1207 return NULL;
1208 }
1209 return (PyObject *)result;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001210}
1211
Raymond Hettingera690a992003-11-16 16:17:49 +00001212static PyObject *
1213set_ior(PySetObject *so, PyObject *other)
1214{
Brian Curtindfc80e32011-08-10 20:28:54 -05001215 if (!PyAnySet_Check(other))
1216 Py_RETURN_NOTIMPLEMENTED;
1217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 if (set_update_internal(so, other) == -1)
1219 return NULL;
1220 Py_INCREF(so);
1221 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001222}
1223
1224static PyObject *
1225set_intersection(PySetObject *so, PyObject *other)
1226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 PySetObject *result;
1228 PyObject *key, *it, *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001229
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 if ((PyObject *)so == other)
1231 return set_copy(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001232
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
1234 if (result == NULL)
1235 return NULL;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 if (PyAnySet_Check(other)) {
1238 Py_ssize_t pos = 0;
1239 setentry *entry;
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1242 tmp = (PyObject *)so;
1243 so = (PySetObject *)other;
1244 other = tmp;
1245 }
Raymond Hettingerb02c35e2005-08-12 20:48:39 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 while (set_next((PySetObject *)other, &pos, &entry)) {
1248 int rv = set_contains_entry(so, entry);
1249 if (rv == -1) {
1250 Py_DECREF(result);
1251 return NULL;
1252 }
1253 if (rv) {
1254 if (set_add_entry(result, entry) == -1) {
1255 Py_DECREF(result);
1256 return NULL;
1257 }
1258 }
1259 }
1260 return (PyObject *)result;
1261 }
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 it = PyObject_GetIter(other);
1264 if (it == NULL) {
1265 Py_DECREF(result);
1266 return NULL;
1267 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001268
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001269 while ((key = PyIter_Next(it)) != NULL) {
1270 int rv;
1271 setentry entry;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001272 Py_hash_t hash = PyObject_Hash(key);
Thomas Wouters89f507f2006-12-13 04:49:30 +00001273
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 if (hash == -1) {
1275 Py_DECREF(it);
1276 Py_DECREF(result);
1277 Py_DECREF(key);
1278 return NULL;
1279 }
1280 entry.hash = hash;
1281 entry.key = key;
1282 rv = set_contains_entry(so, &entry);
1283 if (rv == -1) {
1284 Py_DECREF(it);
1285 Py_DECREF(result);
1286 Py_DECREF(key);
1287 return NULL;
1288 }
1289 if (rv) {
1290 if (set_add_entry(result, &entry) == -1) {
1291 Py_DECREF(it);
1292 Py_DECREF(result);
1293 Py_DECREF(key);
1294 return NULL;
1295 }
1296 }
1297 Py_DECREF(key);
1298 }
1299 Py_DECREF(it);
1300 if (PyErr_Occurred()) {
1301 Py_DECREF(result);
1302 return NULL;
1303 }
1304 return (PyObject *)result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001305}
1306
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001307static PyObject *
1308set_intersection_multi(PySetObject *so, PyObject *args)
1309{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 Py_ssize_t i;
1311 PyObject *result = (PyObject *)so;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 if (PyTuple_GET_SIZE(args) == 0)
1314 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 Py_INCREF(so);
1317 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1318 PyObject *other = PyTuple_GET_ITEM(args, i);
1319 PyObject *newresult = set_intersection((PySetObject *)result, other);
1320 if (newresult == NULL) {
1321 Py_DECREF(result);
1322 return NULL;
1323 }
1324 Py_DECREF(result);
1325 result = newresult;
1326 }
1327 return result;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001328}
1329
Raymond Hettingera690a992003-11-16 16:17:49 +00001330PyDoc_STRVAR(intersection_doc,
1331"Return the intersection of two sets as a new set.\n\
1332\n\
1333(i.e. all elements that are in both sets.)");
1334
1335static PyObject *
1336set_intersection_update(PySetObject *so, PyObject *other)
1337{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 PyObject *tmp;
Raymond Hettingera690a992003-11-16 16:17:49 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 tmp = set_intersection(so, other);
1341 if (tmp == NULL)
1342 return NULL;
1343 set_swap_bodies(so, (PySetObject *)tmp);
1344 Py_DECREF(tmp);
1345 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001346}
1347
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001348static PyObject *
1349set_intersection_update_multi(PySetObject *so, PyObject *args)
1350{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 PyObject *tmp;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 tmp = set_intersection_multi(so, args);
1354 if (tmp == NULL)
1355 return NULL;
1356 set_swap_bodies(so, (PySetObject *)tmp);
1357 Py_DECREF(tmp);
1358 Py_RETURN_NONE;
Georg Brandlc28e1fa2008-06-10 19:20:26 +00001359}
1360
Raymond Hettingera690a992003-11-16 16:17:49 +00001361PyDoc_STRVAR(intersection_update_doc,
1362"Update a set with the intersection of itself and another.");
1363
1364static PyObject *
1365set_and(PySetObject *so, PyObject *other)
1366{
Brian Curtindfc80e32011-08-10 20:28:54 -05001367 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1368 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 return set_intersection(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001370}
1371
1372static PyObject *
1373set_iand(PySetObject *so, PyObject *other)
1374{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001376
Brian Curtindfc80e32011-08-10 20:28:54 -05001377 if (!PyAnySet_Check(other))
1378 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 result = set_intersection_update(so, other);
1380 if (result == NULL)
1381 return NULL;
1382 Py_DECREF(result);
1383 Py_INCREF(so);
1384 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001385}
1386
Guido van Rossum58da9312007-11-10 23:39:45 +00001387static PyObject *
1388set_isdisjoint(PySetObject *so, PyObject *other)
1389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 PyObject *key, *it, *tmp;
Guido van Rossum58da9312007-11-10 23:39:45 +00001391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 if ((PyObject *)so == other) {
1393 if (PySet_GET_SIZE(so) == 0)
1394 Py_RETURN_TRUE;
1395 else
1396 Py_RETURN_FALSE;
1397 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 if (PyAnySet_CheckExact(other)) {
1400 Py_ssize_t pos = 0;
1401 setentry *entry;
Guido van Rossum58da9312007-11-10 23:39:45 +00001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
1404 tmp = (PyObject *)so;
1405 so = (PySetObject *)other;
1406 other = tmp;
1407 }
1408 while (set_next((PySetObject *)other, &pos, &entry)) {
1409 int rv = set_contains_entry(so, entry);
1410 if (rv == -1)
1411 return NULL;
1412 if (rv)
1413 Py_RETURN_FALSE;
1414 }
1415 Py_RETURN_TRUE;
1416 }
Guido van Rossum58da9312007-11-10 23:39:45 +00001417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 it = PyObject_GetIter(other);
1419 if (it == NULL)
1420 return NULL;
Guido van Rossum58da9312007-11-10 23:39:45 +00001421
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 while ((key = PyIter_Next(it)) != NULL) {
1423 int rv;
1424 setentry entry;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001425 Py_hash_t hash = PyObject_Hash(key);
Guido van Rossum58da9312007-11-10 23:39:45 +00001426
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 if (hash == -1) {
1428 Py_DECREF(key);
1429 Py_DECREF(it);
1430 return NULL;
1431 }
1432 entry.hash = hash;
1433 entry.key = key;
1434 rv = set_contains_entry(so, &entry);
1435 Py_DECREF(key);
1436 if (rv == -1) {
1437 Py_DECREF(it);
1438 return NULL;
1439 }
1440 if (rv) {
1441 Py_DECREF(it);
1442 Py_RETURN_FALSE;
1443 }
1444 }
1445 Py_DECREF(it);
1446 if (PyErr_Occurred())
1447 return NULL;
1448 Py_RETURN_TRUE;
Guido van Rossum58da9312007-11-10 23:39:45 +00001449}
1450
1451PyDoc_STRVAR(isdisjoint_doc,
1452"Return True if two sets have a null intersection.");
1453
Neal Norwitz6576bd82005-11-13 18:41:28 +00001454static int
Raymond Hettingerc991db22005-08-11 07:58:45 +00001455set_difference_update_internal(PySetObject *so, PyObject *other)
1456{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 if ((PyObject *)so == other)
1458 return set_clear_internal(so);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 if (PyAnySet_Check(other)) {
1461 setentry *entry;
1462 Py_ssize_t pos = 0;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 while (set_next((PySetObject *)other, &pos, &entry))
1465 if (set_discard_entry(so, entry) == -1)
1466 return -1;
1467 } else {
1468 PyObject *key, *it;
1469 it = PyObject_GetIter(other);
1470 if (it == NULL)
1471 return -1;
1472
1473 while ((key = PyIter_Next(it)) != NULL) {
1474 if (set_discard_key(so, key) == -1) {
1475 Py_DECREF(it);
1476 Py_DECREF(key);
1477 return -1;
1478 }
1479 Py_DECREF(key);
1480 }
1481 Py_DECREF(it);
1482 if (PyErr_Occurred())
1483 return -1;
1484 }
1485 /* If more than 1/5 are dummies, then resize them away. */
1486 if ((so->fill - so->used) * 5 < so->mask)
1487 return 0;
1488 return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
Raymond Hettingerc991db22005-08-11 07:58:45 +00001489}
1490
Raymond Hettingera690a992003-11-16 16:17:49 +00001491static PyObject *
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001492set_difference_update(PySetObject *so, PyObject *args)
Raymond Hettingera690a992003-11-16 16:17:49 +00001493{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 Py_ssize_t i;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
1497 PyObject *other = PyTuple_GET_ITEM(args, i);
1498 if (set_difference_update_internal(so, other) == -1)
1499 return NULL;
1500 }
1501 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001502}
1503
1504PyDoc_STRVAR(difference_update_doc,
1505"Remove all elements of another set from this set.");
1506
1507static PyObject *
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001508set_copy_and_difference(PySetObject *so, PyObject *other)
1509{
1510 PyObject *result;
1511
1512 result = set_copy(so);
1513 if (result == NULL)
1514 return NULL;
1515 if (set_difference_update_internal((PySetObject *) result, other) != -1)
1516 return result;
1517 Py_DECREF(result);
1518 return NULL;
1519}
1520
1521static PyObject *
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001522set_difference(PySetObject *so, PyObject *other)
1523{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 PyObject *result;
1525 setentry *entry;
1526 Py_ssize_t pos = 0;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001527
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001528 if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) {
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001529 return set_copy_and_difference(so, other);
1530 }
1531
1532 /* If len(so) much more than len(other), it's more efficient to simply copy
1533 * so and then iterate other looking for common elements. */
1534 if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) {
1535 return set_copy_and_difference(so, other);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 }
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 result = make_new_set_basetype(Py_TYPE(so), NULL);
1539 if (result == NULL)
1540 return NULL;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001541
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 if (PyDict_CheckExact(other)) {
1543 while (set_next(so, &pos, &entry)) {
1544 setentry entrycopy;
1545 entrycopy.hash = entry->hash;
1546 entrycopy.key = entry->key;
Antoine Pitroufbb1c612010-10-23 17:37:54 +00001547 if (!_PyDict_Contains(other, entry->key, entry->hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 if (set_add_entry((PySetObject *)result, &entrycopy) == -1) {
1549 Py_DECREF(result);
1550 return NULL;
1551 }
1552 }
1553 }
1554 return result;
1555 }
1556
Antoine Pitrou715f3cd2010-11-30 22:23:20 +00001557 /* Iterate over so, checking for common elements in other. */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 while (set_next(so, &pos, &entry)) {
1559 int rv = set_contains_entry((PySetObject *)other, entry);
1560 if (rv == -1) {
1561 Py_DECREF(result);
1562 return NULL;
1563 }
1564 if (!rv) {
1565 if (set_add_entry((PySetObject *)result, entry) == -1) {
1566 Py_DECREF(result);
1567 return NULL;
1568 }
1569 }
1570 }
1571 return result;
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001572}
1573
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001574static PyObject *
1575set_difference_multi(PySetObject *so, PyObject *args)
1576{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 Py_ssize_t i;
1578 PyObject *result, *other;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (PyTuple_GET_SIZE(args) == 0)
1581 return set_copy(so);
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 other = PyTuple_GET_ITEM(args, 0);
1584 result = set_difference(so, other);
1585 if (result == NULL)
1586 return NULL;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
1589 other = PyTuple_GET_ITEM(args, i);
1590 if (set_difference_update_internal((PySetObject *)result, other) == -1) {
1591 Py_DECREF(result);
1592 return NULL;
1593 }
1594 }
1595 return result;
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001596}
1597
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001598PyDoc_STRVAR(difference_doc,
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001599"Return the difference of two or more sets as a new set.\n\
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001600\n\
Amaury Forgeot d'Arcfdfe62d2008-06-17 20:36:03 +00001601(i.e. all elements that are in this set but not the others.)");
Raymond Hettingerfb4e33a2003-12-15 13:23:55 +00001602static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001603set_sub(PySetObject *so, PyObject *other)
1604{
Brian Curtindfc80e32011-08-10 20:28:54 -05001605 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1606 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 return set_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001608}
1609
1610static PyObject *
1611set_isub(PySetObject *so, PyObject *other)
1612{
Brian Curtindfc80e32011-08-10 20:28:54 -05001613 if (!PyAnySet_Check(other))
1614 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001615 if (set_difference_update_internal(so, other) == -1)
1616 return NULL;
1617 Py_INCREF(so);
1618 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001619}
1620
1621static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001622set_symmetric_difference_update(PySetObject *so, PyObject *other)
1623{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001624 PySetObject *otherset;
1625 PyObject *key;
1626 Py_ssize_t pos = 0;
1627 setentry *entry;
Raymond Hettingerc991db22005-08-11 07:58:45 +00001628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 if ((PyObject *)so == other)
1630 return set_clear(so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001631
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 if (PyDict_CheckExact(other)) {
1633 PyObject *value;
1634 int rv;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00001635 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001636 while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
1637 setentry an_entry;
Thomas Wouters89f507f2006-12-13 04:49:30 +00001638
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001639 Py_INCREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001640 an_entry.hash = hash;
1641 an_entry.key = key;
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001643 rv = set_discard_entry(so, &an_entry);
Georg Brandl2d444492010-09-03 10:52:55 +00001644 if (rv == -1) {
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001645 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001647 }
Raymond Hettingerfaf7b7f2010-09-03 10:00:50 +00001648 if (rv == DISCARD_NOTFOUND) {
1649 if (set_add_entry(so, &an_entry) == -1) {
1650 Py_DECREF(key);
1651 return NULL;
1652 }
1653 }
Georg Brandl2d444492010-09-03 10:52:55 +00001654 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001655 }
1656 Py_RETURN_NONE;
1657 }
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 if (PyAnySet_Check(other)) {
1660 Py_INCREF(other);
1661 otherset = (PySetObject *)other;
1662 } else {
1663 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1664 if (otherset == NULL)
1665 return NULL;
1666 }
Raymond Hettingera690a992003-11-16 16:17:49 +00001667
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 while (set_next(otherset, &pos, &entry)) {
1669 int rv = set_discard_entry(so, entry);
1670 if (rv == -1) {
1671 Py_DECREF(otherset);
1672 return NULL;
1673 }
1674 if (rv == DISCARD_NOTFOUND) {
1675 if (set_add_entry(so, entry) == -1) {
1676 Py_DECREF(otherset);
1677 return NULL;
1678 }
1679 }
1680 }
1681 Py_DECREF(otherset);
1682 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001683}
1684
1685PyDoc_STRVAR(symmetric_difference_update_doc,
1686"Update a set with the symmetric difference of itself and another.");
1687
1688static PyObject *
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001689set_symmetric_difference(PySetObject *so, PyObject *other)
1690{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 PyObject *rv;
1692 PySetObject *otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001694 otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
1695 if (otherset == NULL)
1696 return NULL;
1697 rv = set_symmetric_difference_update(otherset, (PyObject *)so);
1698 if (rv == NULL)
1699 return NULL;
1700 Py_DECREF(rv);
1701 return (PyObject *)otherset;
Raymond Hettingerf5f41bf2003-11-24 02:57:33 +00001702}
1703
1704PyDoc_STRVAR(symmetric_difference_doc,
1705"Return the symmetric difference of two sets as a new set.\n\
1706\n\
1707(i.e. all elements that are in exactly one of the sets.)");
1708
1709static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001710set_xor(PySetObject *so, PyObject *other)
1711{
Brian Curtindfc80e32011-08-10 20:28:54 -05001712 if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
1713 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001714 return set_symmetric_difference(so, other);
Raymond Hettingera690a992003-11-16 16:17:49 +00001715}
1716
1717static PyObject *
1718set_ixor(PySetObject *so, PyObject *other)
1719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001720 PyObject *result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001721
Brian Curtindfc80e32011-08-10 20:28:54 -05001722 if (!PyAnySet_Check(other))
1723 Py_RETURN_NOTIMPLEMENTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001724 result = set_symmetric_difference_update(so, other);
1725 if (result == NULL)
1726 return NULL;
1727 Py_DECREF(result);
1728 Py_INCREF(so);
1729 return (PyObject *)so;
Raymond Hettingera690a992003-11-16 16:17:49 +00001730}
1731
1732static PyObject *
1733set_issubset(PySetObject *so, PyObject *other)
1734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 setentry *entry;
1736 Py_ssize_t pos = 0;
Raymond Hettingera690a992003-11-16 16:17:49 +00001737
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 if (!PyAnySet_Check(other)) {
1739 PyObject *tmp, *result;
1740 tmp = make_new_set(&PySet_Type, other);
1741 if (tmp == NULL)
1742 return NULL;
1743 result = set_issubset(so, tmp);
1744 Py_DECREF(tmp);
1745 return result;
1746 }
1747 if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
1748 Py_RETURN_FALSE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 while (set_next(so, &pos, &entry)) {
1751 int rv = set_contains_entry((PySetObject *)other, entry);
1752 if (rv == -1)
1753 return NULL;
1754 if (!rv)
1755 Py_RETURN_FALSE;
1756 }
1757 Py_RETURN_TRUE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001758}
1759
1760PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
1761
1762static PyObject *
1763set_issuperset(PySetObject *so, PyObject *other)
1764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 PyObject *tmp, *result;
Raymond Hettinger3fbec702003-11-21 07:56:36 +00001766
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001767 if (!PyAnySet_Check(other)) {
1768 tmp = make_new_set(&PySet_Type, other);
1769 if (tmp == NULL)
1770 return NULL;
1771 result = set_issuperset(so, tmp);
1772 Py_DECREF(tmp);
1773 return result;
1774 }
1775 return set_issubset((PySetObject *)other, (PyObject *)so);
Raymond Hettingera690a992003-11-16 16:17:49 +00001776}
1777
1778PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
1779
Raymond Hettingera690a992003-11-16 16:17:49 +00001780static PyObject *
1781set_richcompare(PySetObject *v, PyObject *w, int op)
1782{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 PyObject *r1, *r2;
Raymond Hettinger9f1a6792005-07-31 01:16:36 +00001784
Brian Curtindfc80e32011-08-10 20:28:54 -05001785 if(!PyAnySet_Check(w))
1786 Py_RETURN_NOTIMPLEMENTED;
1787
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001788 switch (op) {
1789 case Py_EQ:
1790 if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
1791 Py_RETURN_FALSE;
1792 if (v->hash != -1 &&
1793 ((PySetObject *)w)->hash != -1 &&
1794 v->hash != ((PySetObject *)w)->hash)
1795 Py_RETURN_FALSE;
1796 return set_issubset(v, w);
1797 case Py_NE:
1798 r1 = set_richcompare(v, w, Py_EQ);
1799 if (r1 == NULL)
1800 return NULL;
1801 r2 = PyBool_FromLong(PyObject_Not(r1));
1802 Py_DECREF(r1);
1803 return r2;
1804 case Py_LE:
1805 return set_issubset(v, w);
1806 case Py_GE:
1807 return set_issuperset(v, w);
1808 case Py_LT:
1809 if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
1810 Py_RETURN_FALSE;
1811 return set_issubset(v, w);
1812 case Py_GT:
1813 if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
1814 Py_RETURN_FALSE;
1815 return set_issuperset(v, w);
1816 }
Brian Curtindfc80e32011-08-10 20:28:54 -05001817 Py_RETURN_NOTIMPLEMENTED;
Raymond Hettingera690a992003-11-16 16:17:49 +00001818}
1819
Raymond Hettingera690a992003-11-16 16:17:49 +00001820static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001821set_add(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001823 if (set_add_key(so, key) == -1)
1824 return NULL;
1825 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001826}
1827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828PyDoc_STRVAR(add_doc,
Raymond Hettingera690a992003-11-16 16:17:49 +00001829"Add an element to a set.\n\
1830\n\
1831This has no effect if the element is already present.");
1832
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001833static int
1834set_contains(PySetObject *so, PyObject *key)
1835{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001836 PyObject *tmpkey;
1837 int rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001838
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 rv = set_contains_key(so, key);
1840 if (rv == -1) {
1841 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1842 return -1;
1843 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001844 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 if (tmpkey == NULL)
1846 return -1;
Petri Lehtinen5acc27e2011-10-30 13:56:41 +02001847 rv = set_contains_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 Py_DECREF(tmpkey);
1849 }
1850 return rv;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001851}
1852
1853static PyObject *
1854set_direct_contains(PySetObject *so, PyObject *key)
1855{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 long result;
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001857
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 result = set_contains(so, key);
1859 if (result == -1)
1860 return NULL;
1861 return PyBool_FromLong(result);
Raymond Hettingerce8185e2005-08-13 09:28:48 +00001862}
1863
1864PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
1865
Raymond Hettingera690a992003-11-16 16:17:49 +00001866static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001867set_remove(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 PyObject *tmpkey;
1870 int rv;
Raymond Hettingerbfd334a2003-11-22 03:55:23 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 rv = set_discard_key(so, key);
1873 if (rv == -1) {
1874 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1875 return NULL;
1876 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001877 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 if (tmpkey == NULL)
1879 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001880 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001881 Py_DECREF(tmpkey);
1882 if (rv == -1)
1883 return NULL;
1884 }
Benjamin Petersonf10a79a2008-10-11 00:49:57 +00001885
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 if (rv == DISCARD_NOTFOUND) {
Raymond Hettinger69492da2013-09-02 15:59:26 -07001887 _PyErr_SetKeyError(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 return NULL;
1889 }
1890 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001891}
1892
1893PyDoc_STRVAR(remove_doc,
1894"Remove an element from a set; it must be a member.\n\
1895\n\
1896If the element is not a member, raise a KeyError.");
1897
1898static PyObject *
Raymond Hettinger06d8cf82005-07-31 15:36:06 +00001899set_discard(PySetObject *so, PyObject *key)
Raymond Hettingera690a992003-11-16 16:17:49 +00001900{
Benjamin Peterson2b50a012011-10-30 14:24:44 -04001901 PyObject *tmpkey;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 int rv;
Raymond Hettinger0deab622003-12-13 18:53:18 +00001903
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 rv = set_discard_key(so, key);
1905 if (rv == -1) {
1906 if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
1907 return NULL;
1908 PyErr_Clear();
Raymond Hettinger38bf2cc2010-08-06 09:52:17 +00001909 tmpkey = make_new_set(&PyFrozenSet_Type, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 if (tmpkey == NULL)
1911 return NULL;
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001912 rv = set_discard_key(so, tmpkey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 Py_DECREF(tmpkey);
Petri Lehtinene0aa8032011-10-30 14:31:27 +02001914 if (rv == -1)
1915 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001916 }
1917 Py_RETURN_NONE;
Raymond Hettingera690a992003-11-16 16:17:49 +00001918}
1919
1920PyDoc_STRVAR(discard_doc,
1921"Remove an element from a set if it is a member.\n\
1922\n\
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923If the element is not a member, do nothing.");
Raymond Hettingera690a992003-11-16 16:17:49 +00001924
1925static PyObject *
Raymond Hettingera690a992003-11-16 16:17:49 +00001926set_reduce(PySetObject *so)
1927{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 PyObject *keys=NULL, *args=NULL, *result=NULL, *dict=NULL;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001929 _Py_IDENTIFIER(__dict__);
Raymond Hettingera690a992003-11-16 16:17:49 +00001930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 keys = PySequence_List((PyObject *)so);
1932 if (keys == NULL)
1933 goto done;
1934 args = PyTuple_Pack(1, keys);
1935 if (args == NULL)
1936 goto done;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001937 dict = _PyObject_GetAttrId((PyObject *)so, &PyId___dict__);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 if (dict == NULL) {
1939 PyErr_Clear();
1940 dict = Py_None;
1941 Py_INCREF(dict);
1942 }
1943 result = PyTuple_Pack(3, Py_TYPE(so), args, dict);
Raymond Hettingera690a992003-11-16 16:17:49 +00001944done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001945 Py_XDECREF(args);
1946 Py_XDECREF(keys);
1947 Py_XDECREF(dict);
1948 return result;
Raymond Hettingera690a992003-11-16 16:17:49 +00001949}
1950
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001951static PyObject *
1952set_sizeof(PySetObject *so)
1953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 Py_ssize_t res;
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 res = sizeof(PySetObject);
1957 if (so->table != so->smalltable)
1958 res = res + (so->mask + 1) * sizeof(setentry);
1959 return PyLong_FromSsize_t(res);
Robert Schuppeniesfbe94c52008-07-14 10:13:31 +00001960}
1961
1962PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001963static int
1964set_init(PySetObject *self, PyObject *args, PyObject *kwds)
1965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 PyObject *iterable = NULL;
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 if (!PyAnySet_Check(self))
1969 return -1;
1970 if (PySet_Check(self) && !_PyArg_NoKeywords("set()", kwds))
1971 return -1;
1972 if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
1973 return -1;
1974 set_clear_internal(self);
1975 self->hash = -1;
1976 if (iterable == NULL)
1977 return 0;
1978 return set_update_internal(self, iterable);
Raymond Hettinger50a4bb32003-11-17 16:42:33 +00001979}
1980
Raymond Hettingera690a992003-11-16 16:17:49 +00001981static PySequenceMethods set_as_sequence = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 set_len, /* sq_length */
1983 0, /* sq_concat */
1984 0, /* sq_repeat */
1985 0, /* sq_item */
1986 0, /* sq_slice */
1987 0, /* sq_ass_item */
1988 0, /* sq_ass_slice */
1989 (objobjproc)set_contains, /* sq_contains */
Raymond Hettingera690a992003-11-16 16:17:49 +00001990};
1991
1992/* set object ********************************************************/
1993
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00001994#ifdef Py_DEBUG
1995static PyObject *test_c_api(PySetObject *so);
1996
1997PyDoc_STRVAR(test_c_api_doc, "Exercises C API. Returns True.\n\
1998All is well if assertions don't fail.");
1999#endif
2000
Raymond Hettingera690a992003-11-16 16:17:49 +00002001static PyMethodDef set_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002002 {"add", (PyCFunction)set_add, METH_O,
2003 add_doc},
2004 {"clear", (PyCFunction)set_clear, METH_NOARGS,
2005 clear_doc},
2006 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2007 contains_doc},
2008 {"copy", (PyCFunction)set_copy, METH_NOARGS,
2009 copy_doc},
2010 {"discard", (PyCFunction)set_discard, METH_O,
2011 discard_doc},
2012 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2013 difference_doc},
2014 {"difference_update", (PyCFunction)set_difference_update, METH_VARARGS,
2015 difference_update_doc},
2016 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2017 intersection_doc},
2018 {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
2019 intersection_update_doc},
2020 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2021 isdisjoint_doc},
2022 {"issubset", (PyCFunction)set_issubset, METH_O,
2023 issubset_doc},
2024 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2025 issuperset_doc},
2026 {"pop", (PyCFunction)set_pop, METH_NOARGS,
2027 pop_doc},
2028 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2029 reduce_doc},
2030 {"remove", (PyCFunction)set_remove, METH_O,
2031 remove_doc},
2032 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2033 sizeof_doc},
2034 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2035 symmetric_difference_doc},
2036 {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update, METH_O,
2037 symmetric_difference_update_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002038#ifdef Py_DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002039 {"test_c_api", (PyCFunction)test_c_api, METH_NOARGS,
2040 test_c_api_doc},
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002041#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002042 {"union", (PyCFunction)set_union, METH_VARARGS,
2043 union_doc},
2044 {"update", (PyCFunction)set_update, METH_VARARGS,
2045 update_doc},
2046 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002047};
2048
2049static PyNumberMethods set_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 0, /*nb_add*/
2051 (binaryfunc)set_sub, /*nb_subtract*/
2052 0, /*nb_multiply*/
2053 0, /*nb_remainder*/
2054 0, /*nb_divmod*/
2055 0, /*nb_power*/
2056 0, /*nb_negative*/
2057 0, /*nb_positive*/
2058 0, /*nb_absolute*/
2059 0, /*nb_bool*/
2060 0, /*nb_invert*/
2061 0, /*nb_lshift*/
2062 0, /*nb_rshift*/
2063 (binaryfunc)set_and, /*nb_and*/
2064 (binaryfunc)set_xor, /*nb_xor*/
2065 (binaryfunc)set_or, /*nb_or*/
2066 0, /*nb_int*/
2067 0, /*nb_reserved*/
2068 0, /*nb_float*/
2069 0, /*nb_inplace_add*/
2070 (binaryfunc)set_isub, /*nb_inplace_subtract*/
2071 0, /*nb_inplace_multiply*/
2072 0, /*nb_inplace_remainder*/
2073 0, /*nb_inplace_power*/
2074 0, /*nb_inplace_lshift*/
2075 0, /*nb_inplace_rshift*/
2076 (binaryfunc)set_iand, /*nb_inplace_and*/
2077 (binaryfunc)set_ixor, /*nb_inplace_xor*/
2078 (binaryfunc)set_ior, /*nb_inplace_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002079};
2080
2081PyDoc_STRVAR(set_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002082"set() -> new empty set object\n\
2083set(iterable) -> new set object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002084\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002085Build an unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002086
2087PyTypeObject PySet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2089 "set", /* tp_name */
2090 sizeof(PySetObject), /* tp_basicsize */
2091 0, /* tp_itemsize */
2092 /* methods */
2093 (destructor)set_dealloc, /* tp_dealloc */
2094 0, /* tp_print */
2095 0, /* tp_getattr */
2096 0, /* tp_setattr */
2097 0, /* tp_reserved */
2098 (reprfunc)set_repr, /* tp_repr */
2099 &set_as_number, /* tp_as_number */
2100 &set_as_sequence, /* tp_as_sequence */
2101 0, /* tp_as_mapping */
Georg Brandl00da4e02010-10-18 07:32:48 +00002102 PyObject_HashNotImplemented, /* tp_hash */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 0, /* tp_call */
2104 0, /* tp_str */
2105 PyObject_GenericGetAttr, /* tp_getattro */
2106 0, /* tp_setattro */
2107 0, /* tp_as_buffer */
2108 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2109 Py_TPFLAGS_BASETYPE, /* tp_flags */
2110 set_doc, /* tp_doc */
2111 (traverseproc)set_traverse, /* tp_traverse */
2112 (inquiry)set_clear_internal, /* tp_clear */
2113 (richcmpfunc)set_richcompare, /* tp_richcompare */
Georg Brandl00da4e02010-10-18 07:32:48 +00002114 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2115 (getiterfunc)set_iter, /* tp_iter */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002116 0, /* tp_iternext */
2117 set_methods, /* tp_methods */
2118 0, /* tp_members */
2119 0, /* tp_getset */
2120 0, /* tp_base */
2121 0, /* tp_dict */
2122 0, /* tp_descr_get */
2123 0, /* tp_descr_set */
2124 0, /* tp_dictoffset */
2125 (initproc)set_init, /* tp_init */
2126 PyType_GenericAlloc, /* tp_alloc */
2127 set_new, /* tp_new */
2128 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002129};
2130
2131/* frozenset object ********************************************************/
2132
2133
2134static PyMethodDef frozenset_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 {"__contains__",(PyCFunction)set_direct_contains, METH_O | METH_COEXIST,
2136 contains_doc},
2137 {"copy", (PyCFunction)frozenset_copy, METH_NOARGS,
2138 copy_doc},
2139 {"difference", (PyCFunction)set_difference_multi, METH_VARARGS,
2140 difference_doc},
2141 {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
2142 intersection_doc},
2143 {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
2144 isdisjoint_doc},
2145 {"issubset", (PyCFunction)set_issubset, METH_O,
2146 issubset_doc},
2147 {"issuperset", (PyCFunction)set_issuperset, METH_O,
2148 issuperset_doc},
2149 {"__reduce__", (PyCFunction)set_reduce, METH_NOARGS,
2150 reduce_doc},
2151 {"__sizeof__", (PyCFunction)set_sizeof, METH_NOARGS,
2152 sizeof_doc},
2153 {"symmetric_difference",(PyCFunction)set_symmetric_difference, METH_O,
2154 symmetric_difference_doc},
2155 {"union", (PyCFunction)set_union, METH_VARARGS,
2156 union_doc},
2157 {NULL, NULL} /* sentinel */
Raymond Hettingera690a992003-11-16 16:17:49 +00002158};
2159
2160static PyNumberMethods frozenset_as_number = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 0, /*nb_add*/
2162 (binaryfunc)set_sub, /*nb_subtract*/
2163 0, /*nb_multiply*/
2164 0, /*nb_remainder*/
2165 0, /*nb_divmod*/
2166 0, /*nb_power*/
2167 0, /*nb_negative*/
2168 0, /*nb_positive*/
2169 0, /*nb_absolute*/
2170 0, /*nb_bool*/
2171 0, /*nb_invert*/
2172 0, /*nb_lshift*/
2173 0, /*nb_rshift*/
2174 (binaryfunc)set_and, /*nb_and*/
2175 (binaryfunc)set_xor, /*nb_xor*/
2176 (binaryfunc)set_or, /*nb_or*/
Raymond Hettingera690a992003-11-16 16:17:49 +00002177};
2178
2179PyDoc_STRVAR(frozenset_doc,
Ezio Melotti7f807b72010-03-01 04:08:34 +00002180"frozenset() -> empty frozenset object\n\
2181frozenset(iterable) -> frozenset object\n\
Raymond Hettingera690a992003-11-16 16:17:49 +00002182\n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002183Build an immutable unordered collection of unique elements.");
Raymond Hettingera690a992003-11-16 16:17:49 +00002184
2185PyTypeObject PyFrozenSet_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002186 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2187 "frozenset", /* tp_name */
2188 sizeof(PySetObject), /* tp_basicsize */
2189 0, /* tp_itemsize */
2190 /* methods */
2191 (destructor)set_dealloc, /* tp_dealloc */
2192 0, /* tp_print */
2193 0, /* tp_getattr */
2194 0, /* tp_setattr */
2195 0, /* tp_reserved */
2196 (reprfunc)set_repr, /* tp_repr */
2197 &frozenset_as_number, /* tp_as_number */
2198 &set_as_sequence, /* tp_as_sequence */
2199 0, /* tp_as_mapping */
2200 frozenset_hash, /* tp_hash */
2201 0, /* tp_call */
2202 0, /* tp_str */
2203 PyObject_GenericGetAttr, /* tp_getattro */
2204 0, /* tp_setattro */
2205 0, /* tp_as_buffer */
2206 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
2207 Py_TPFLAGS_BASETYPE, /* tp_flags */
2208 frozenset_doc, /* tp_doc */
2209 (traverseproc)set_traverse, /* tp_traverse */
2210 (inquiry)set_clear_internal, /* tp_clear */
2211 (richcmpfunc)set_richcompare, /* tp_richcompare */
2212 offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
2213 (getiterfunc)set_iter, /* tp_iter */
2214 0, /* tp_iternext */
2215 frozenset_methods, /* tp_methods */
2216 0, /* tp_members */
2217 0, /* tp_getset */
2218 0, /* tp_base */
2219 0, /* tp_dict */
2220 0, /* tp_descr_get */
2221 0, /* tp_descr_set */
2222 0, /* tp_dictoffset */
2223 0, /* tp_init */
2224 PyType_GenericAlloc, /* tp_alloc */
2225 frozenset_new, /* tp_new */
2226 PyObject_GC_Del, /* tp_free */
Raymond Hettingera690a992003-11-16 16:17:49 +00002227};
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002228
2229
2230/***** C API functions *************************************************/
2231
2232PyObject *
2233PySet_New(PyObject *iterable)
2234{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002235 return make_new_set(&PySet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002236}
2237
2238PyObject *
2239PyFrozenSet_New(PyObject *iterable)
2240{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002241 return make_new_set(&PyFrozenSet_Type, iterable);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002242}
2243
Neal Norwitz8c49c822006-03-04 18:41:19 +00002244Py_ssize_t
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002245PySet_Size(PyObject *anyset)
2246{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 if (!PyAnySet_Check(anyset)) {
2248 PyErr_BadInternalCall();
2249 return -1;
2250 }
2251 return PySet_GET_SIZE(anyset);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002252}
2253
2254int
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002255PySet_Clear(PyObject *set)
2256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002257 if (!PySet_Check(set)) {
2258 PyErr_BadInternalCall();
2259 return -1;
2260 }
2261 return set_clear_internal((PySetObject *)set);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002262}
2263
2264int
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002265PySet_Contains(PyObject *anyset, PyObject *key)
2266{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002267 if (!PyAnySet_Check(anyset)) {
2268 PyErr_BadInternalCall();
2269 return -1;
2270 }
2271 return set_contains_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002272}
2273
2274int
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002275PySet_Discard(PyObject *set, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002277 if (!PySet_Check(set)) {
2278 PyErr_BadInternalCall();
2279 return -1;
2280 }
2281 return set_discard_key((PySetObject *)set, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002282}
2283
2284int
Christian Heimesfd66e512008-01-29 12:18:50 +00002285PySet_Add(PyObject *anyset, PyObject *key)
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002286{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 if (!PySet_Check(anyset) &&
2288 (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
2289 PyErr_BadInternalCall();
2290 return -1;
2291 }
2292 return set_add_key((PySetObject *)anyset, key);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002293}
2294
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002295int
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002296_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
Guido van Rossumd8faa362007-04-27 19:54:29 +00002297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002298 setentry *entry;
Guido van Rossumd8faa362007-04-27 19:54:29 +00002299
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002300 if (!PyAnySet_Check(set)) {
2301 PyErr_BadInternalCall();
2302 return -1;
2303 }
2304 if (set_next((PySetObject *)set, pos, &entry) == 0)
2305 return 0;
2306 *key = entry->key;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002307 *hash = entry->hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002308 return 1;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002309}
2310
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002311PyObject *
2312PySet_Pop(PyObject *set)
2313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 if (!PySet_Check(set)) {
2315 PyErr_BadInternalCall();
2316 return NULL;
2317 }
2318 return set_pop((PySetObject *)set);
Raymond Hettingerbeb31012005-08-16 03:47:52 +00002319}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002320
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002321int
2322_PySet_Update(PyObject *set, PyObject *iterable)
2323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002324 if (!PySet_Check(set)) {
2325 PyErr_BadInternalCall();
2326 return -1;
2327 }
2328 return set_update_internal((PySetObject *)set, iterable);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002329}
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002330
Raymond Hettingere259f132013-12-15 11:56:14 -08002331/* Exported for the gdb plugin's benefit. */
2332PyObject *_PySet_Dummy = dummy;
2333
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002334#ifdef Py_DEBUG
2335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336/* Test code to be called with any three element set.
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002337 Returns True and original set is restored. */
2338
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339#define assertRaises(call_return_value, exception) \
2340 do { \
2341 assert(call_return_value); \
2342 assert(PyErr_ExceptionMatches(exception)); \
2343 PyErr_Clear(); \
2344 } while(0)
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002345
2346static PyObject *
2347test_c_api(PySetObject *so)
2348{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002349 Py_ssize_t count;
2350 char *s;
2351 Py_ssize_t i;
Raymond Hettinger583cd032013-09-07 22:06:35 -07002352 PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 PyObject *ob = (PyObject *)so;
Benjamin Peterson8f67d082010-10-17 20:54:53 +00002354 Py_hash_t hash;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002355 PyObject *str;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 /* Verify preconditions */
2358 assert(PyAnySet_Check(ob));
2359 assert(PyAnySet_CheckExact(ob));
2360 assert(!PyFrozenSet_CheckExact(ob));
Victor Stinner08b36bd2010-03-13 00:19:17 +00002361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 /* so.clear(); so |= set("abc"); */
2363 str = PyUnicode_FromString("abc");
2364 if (str == NULL)
2365 return NULL;
2366 set_clear_internal(so);
2367 if (set_update_internal(so, str) == -1) {
2368 Py_DECREF(str);
2369 return NULL;
2370 }
2371 Py_DECREF(str);
Victor Stinner08b36bd2010-03-13 00:19:17 +00002372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002373 /* Exercise type/size checks */
2374 assert(PySet_Size(ob) == 3);
2375 assert(PySet_GET_SIZE(ob) == 3);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002377 /* Raise TypeError for non-iterable constructor arguments */
2378 assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
2379 assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 /* Raise TypeError for unhashable key */
2382 dup = PySet_New(ob);
2383 assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
2384 assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
2385 assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Exercise successful pop, contains, add, and discard */
2388 elem = PySet_Pop(ob);
2389 assert(PySet_Contains(ob, elem) == 0);
2390 assert(PySet_GET_SIZE(ob) == 2);
2391 assert(PySet_Add(ob, elem) == 0);
2392 assert(PySet_Contains(ob, elem) == 1);
2393 assert(PySet_GET_SIZE(ob) == 3);
2394 assert(PySet_Discard(ob, elem) == 1);
2395 assert(PySet_GET_SIZE(ob) == 2);
2396 assert(PySet_Discard(ob, elem) == 0);
2397 assert(PySet_GET_SIZE(ob) == 2);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002399 /* Exercise clear */
2400 dup2 = PySet_New(dup);
2401 assert(PySet_Clear(dup2) == 0);
2402 assert(PySet_Size(dup2) == 0);
2403 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002404
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002405 /* Raise SystemError on clear or update of frozen set */
2406 f = PyFrozenSet_New(dup);
2407 assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
2408 assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
2409 assert(PySet_Add(f, elem) == 0);
2410 Py_INCREF(f);
2411 assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
2412 Py_DECREF(f);
2413 Py_DECREF(f);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002414
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002415 /* Exercise direct iteration */
2416 i = 0, count = 0;
2417 while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
2418 s = _PyUnicode_AsString(x);
2419 assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
2420 count++;
2421 }
2422 assert(count == 3);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002424 /* Exercise updates */
2425 dup2 = PySet_New(NULL);
2426 assert(_PySet_Update(dup2, dup) == 0);
2427 assert(PySet_Size(dup2) == 3);
2428 assert(_PySet_Update(dup2, dup) == 0);
2429 assert(PySet_Size(dup2) == 3);
2430 Py_DECREF(dup2);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00002431
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002432 /* Raise SystemError when self argument is not a set or frozenset. */
2433 t = PyTuple_New(0);
2434 assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
2435 assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
2436 Py_DECREF(t);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002438 /* Raise SystemError when self argument is not a set. */
2439 f = PyFrozenSet_New(dup);
2440 assert(PySet_Size(f) == 3);
2441 assert(PyFrozenSet_CheckExact(f));
2442 assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
2443 assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
2444 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002446 /* Raise KeyError when popping from an empty set */
2447 assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
2448 Py_DECREF(ob);
2449 assert(PySet_GET_SIZE(ob) == 0);
2450 assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002451
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002452 /* Restore the set from the copy using the PyNumber API */
2453 assert(PyNumber_InPlaceOr(ob, dup) == ob);
2454 Py_DECREF(ob);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002456 /* Verify constructors accept NULL arguments */
2457 f = PySet_New(NULL);
2458 assert(f != NULL);
2459 assert(PySet_GET_SIZE(f) == 0);
2460 Py_DECREF(f);
2461 f = PyFrozenSet_New(NULL);
2462 assert(f != NULL);
2463 assert(PyFrozenSet_CheckExact(f));
2464 assert(PySet_GET_SIZE(f) == 0);
2465 Py_DECREF(f);
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002467 Py_DECREF(elem);
2468 Py_DECREF(dup);
2469 Py_RETURN_TRUE;
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002470}
2471
Raymond Hettinger9bda1d62005-09-16 07:14:21 +00002472#undef assertRaises
2473
Raymond Hettingerc47e01d2005-08-16 10:44:15 +00002474#endif
Raymond Hettingerbfc1e1a2013-08-23 03:22:15 -05002475
2476/***** Dummy Struct *************************************************/
2477
2478static PyObject *
2479dummy_repr(PyObject *op)
2480{
2481 return PyUnicode_FromString("<dummy key>");
2482}
2483
2484static void
2485dummy_dealloc(PyObject* ignore)
2486{
2487 Py_FatalError("deallocating <dummy key>");
2488}
2489
2490static PyTypeObject _PySetDummy_Type = {
2491 PyVarObject_HEAD_INIT(&PyType_Type, 0)
2492 "<dummy key> type",
2493 0,
2494 0,
2495 dummy_dealloc, /*tp_dealloc*/ /*never called*/
2496 0, /*tp_print*/
2497 0, /*tp_getattr*/
2498 0, /*tp_setattr*/
2499 0, /*tp_reserved*/
2500 dummy_repr, /*tp_repr*/
2501 0, /*tp_as_number*/
2502 0, /*tp_as_sequence*/
2503 0, /*tp_as_mapping*/
2504 0, /*tp_hash */
2505 0, /*tp_call */
2506 0, /*tp_str */
2507 0, /*tp_getattro */
2508 0, /*tp_setattro */
2509 0, /*tp_as_buffer */
2510 Py_TPFLAGS_DEFAULT, /*tp_flags */
2511};
2512
2513static PyObject _dummy_struct = {
2514 _PyObject_EXTRA_INIT
2515 2, &_PySetDummy_Type
2516};
2517