LCOV - code coverage report
Current view: top level - Objects - setobject.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 965 1073 89.9 %
Date: 2022-07-20 13:12:14 Functions: 80 83 96.4 %
Branches: 697 829 84.1 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : /* set object implementation
       3                 :            : 
       4                 :            :    Written and maintained by Raymond D. Hettinger <python@rcn.com>
       5                 :            :    Derived from Lib/sets.py and Objects/dictobject.c.
       6                 :            : 
       7                 :            :    The basic lookup function used by all operations.
       8                 :            :    This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.
       9                 :            : 
      10                 :            :    The initial probe index is computed as hash mod the table size.
      11                 :            :    Subsequent probe indices are computed as explained in Objects/dictobject.c.
      12                 :            : 
      13                 :            :    To improve cache locality, each probe inspects a series of consecutive
      14                 :            :    nearby entries before moving on to probes elsewhere in memory.  This leaves
      15                 :            :    us with a hybrid of linear probing and randomized probing.  The linear probing
      16                 :            :    reduces the cost of hash collisions because consecutive memory accesses
      17                 :            :    tend to be much cheaper than scattered probes.  After LINEAR_PROBES steps,
      18                 :            :    we then use more of the upper bits from the hash value and apply a simple
      19                 :            :    linear congruential random number generator.  This helps break-up long
      20                 :            :    chains of collisions.
      21                 :            : 
      22                 :            :    All arithmetic on hash should ignore overflow.
      23                 :            : 
      24                 :            :    Unlike the dictionary implementation, the lookkey function can return
      25                 :            :    NULL if the rich comparison returns an error.
      26                 :            : 
      27                 :            :    Use cases for sets differ considerably from dictionaries where looked-up
      28                 :            :    keys are more likely to be present.  In contrast, sets are primarily
      29                 :            :    about membership testing where the presence of an element is not known in
      30                 :            :    advance.  Accordingly, the set implementation needs to optimize for both
      31                 :            :    the found and not-found case.
      32                 :            : */
      33                 :            : 
      34                 :            : #include "Python.h"
      35                 :            : #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
      36                 :            : #include <stddef.h>               // offsetof()
      37                 :            : 
      38                 :            : /* Object used as dummy key to fill deleted entries */
      39                 :            : static PyObject _dummy_struct;
      40                 :            : 
      41                 :            : #define dummy (&_dummy_struct)
      42                 :            : 
      43                 :            : 
      44                 :            : /* ======================================================================== */
      45                 :            : /* ======= Begin logic for probing the hash table ========================= */
      46                 :            : 
      47                 :            : /* Set this to zero to turn-off linear probing */
      48                 :            : #ifndef LINEAR_PROBES
      49                 :            : #define LINEAR_PROBES 9
      50                 :            : #endif
      51                 :            : 
      52                 :            : /* This must be >= 1 */
      53                 :            : #define PERTURB_SHIFT 5
      54                 :            : 
      55                 :            : static setentry *
      56                 :   39969485 : set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
      57                 :            : {
      58                 :            :     setentry *table;
      59                 :            :     setentry *entry;
      60                 :   39969485 :     size_t perturb = hash;
      61                 :   39969485 :     size_t mask = so->mask;
      62                 :   39969485 :     size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
      63                 :            :     int probes;
      64                 :            :     int cmp;
      65                 :            : 
      66                 :            :     while (1) {
      67                 :   42910992 :         entry = &so->table[i];
      68         [ +  + ]:   42910992 :         probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
      69                 :            :         do {
      70   [ +  +  +  + ]:   77192582 :             if (entry->hash == 0 && entry->key == NULL)
      71                 :   34386036 :                 return entry;
      72         [ +  + ]:   42806546 :             if (entry->hash == hash) {
      73                 :    5617880 :                 PyObject *startkey = entry->key;
      74                 :            :                 assert(startkey != dummy);
      75         [ +  + ]:    5617880 :                 if (startkey == key)
      76                 :    3893801 :                     return entry;
      77         [ +  + ]:    1724079 :                 if (PyUnicode_CheckExact(startkey)
      78         [ +  + ]:     634005 :                     && PyUnicode_CheckExact(key)
      79         [ +  - ]:     633923 :                     && _PyUnicode_EQ(startkey, key))
      80                 :     633923 :                     return entry;
      81                 :    1090156 :                 table = so->table;
      82                 :    1090156 :                 Py_INCREF(startkey);
      83                 :    1090156 :                 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
      84                 :    1090156 :                 Py_DECREF(startkey);
      85         [ +  + ]:    1090156 :                 if (cmp < 0)
      86                 :          8 :                     return NULL;
      87   [ +  +  +  + ]:    1090148 :                 if (table != so->table || entry->key != startkey)
      88                 :       2729 :                     return set_lookkey(so, key, hash);
      89         [ +  + ]:    1087419 :                 if (cmp > 0)
      90                 :    1052988 :                     return entry;
      91                 :      34431 :                 mask = so->mask;
      92                 :            :             }
      93                 :   37223097 :             entry++;
      94         [ +  + ]:   37223097 :         } while (probes--);
      95                 :    2941507 :         perturb >>= PERTURB_SHIFT;
      96                 :    2941507 :         i = (i * 5 + 1 + perturb) & mask;
      97                 :            :     }
      98                 :            : }
      99                 :            : 
     100                 :            : static int set_table_resize(PySetObject *, Py_ssize_t);
     101                 :            : 
     102                 :            : static int
     103                 :   23593493 : set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
     104                 :            : {
     105                 :            :     setentry *table;
     106                 :            :     setentry *freeslot;
     107                 :            :     setentry *entry;
     108                 :            :     size_t perturb;
     109                 :            :     size_t mask;
     110                 :            :     size_t i;                       /* Unsigned for defined overflow behavior */
     111                 :            :     int probes;
     112                 :            :     int cmp;
     113                 :            : 
     114                 :            :     /* Pre-increment is necessary to prevent arbitrary code in the rich
     115                 :            :        comparison from deallocating the key just before the insertion. */
     116                 :   23593493 :     Py_INCREF(key);
     117                 :            : 
     118                 :   23593917 :   restart:
     119                 :            : 
     120                 :   23593917 :     mask = so->mask;
     121                 :   23593917 :     i = (size_t)hash & mask;
     122                 :   23593917 :     freeslot = NULL;
     123                 :   23593917 :     perturb = hash;
     124                 :            : 
     125                 :            :     while (1) {
     126                 :   27908697 :         entry = &so->table[i];
     127         [ +  + ]:   27908697 :         probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
     128                 :            :         do {
     129   [ +  +  +  + ]:   45312411 :             if (entry->hash == 0 && entry->key == NULL)
     130                 :   21343992 :                 goto found_unused_or_dummy;
     131         [ +  + ]:   23968419 :             if (entry->hash == hash) {
     132                 :    9319464 :                 PyObject *startkey = entry->key;
     133                 :            :                 assert(startkey != dummy);
     134         [ +  + ]:    9319464 :                 if (startkey == key)
     135                 :    1689015 :                     goto found_active;
     136         [ +  + ]:    7630449 :                 if (PyUnicode_CheckExact(startkey)
     137         [ +  + ]:     111420 :                     && PyUnicode_CheckExact(key)
     138         [ +  - ]:     111287 :                     && _PyUnicode_EQ(startkey, key))
     139                 :     111287 :                     goto found_active;
     140                 :    7519162 :                 table = so->table;
     141                 :    7519162 :                 Py_INCREF(startkey);
     142                 :    7519162 :                 cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
     143                 :    7519162 :                 Py_DECREF(startkey);
     144         [ +  + ]:    7519162 :                 if (cmp > 0)
     145                 :     449192 :                     goto found_active;
     146         [ +  + ]:    7069970 :                 if (cmp < 0)
     147                 :          7 :                     goto comparison_error;
     148   [ +  +  +  + ]:    7069963 :                 if (table != so->table || entry->key != startkey)
     149                 :        424 :                     goto restart;
     150                 :    7069539 :                 mask = so->mask;
     151                 :            :             }
     152         [ +  + ]:   14648955 :             else if (entry->hash == -1) {
     153                 :            :                 assert (entry->key == dummy);
     154                 :     115133 :                 freeslot = entry;
     155                 :            :             }
     156                 :   21718494 :             entry++;
     157         [ +  + ]:   21718494 :         } while (probes--);
     158                 :    4314780 :         perturb >>= PERTURB_SHIFT;
     159                 :    4314780 :         i = (i * 5 + 1 + perturb) & mask;
     160                 :            :     }
     161                 :            : 
     162                 :   21343992 :   found_unused_or_dummy:
     163         [ +  + ]:   21343992 :     if (freeslot == NULL)
     164                 :   21279252 :         goto found_unused;
     165                 :      64740 :     so->used++;
     166                 :      64740 :     freeslot->key = key;
     167                 :      64740 :     freeslot->hash = hash;
     168                 :      64740 :     return 0;
     169                 :            : 
     170                 :   21279252 :   found_unused:
     171                 :   21279252 :     so->fill++;
     172                 :   21279252 :     so->used++;
     173                 :   21279252 :     entry->key = key;
     174                 :   21279252 :     entry->hash = hash;
     175         [ +  + ]:   21279252 :     if ((size_t)so->fill*5 < mask*3)
     176                 :   19771673 :         return 0;
     177         [ +  + ]:    1507579 :     return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
     178                 :            : 
     179                 :    2249494 :   found_active:
     180                 :    2249494 :     Py_DECREF(key);
     181                 :    2249494 :     return 0;
     182                 :            : 
     183                 :          7 :   comparison_error:
     184                 :          7 :     Py_DECREF(key);
     185                 :          7 :     return -1;
     186                 :            : }
     187                 :            : 
     188                 :            : /*
     189                 :            : Internal routine used by set_table_resize() to insert an item which is
     190                 :            : known to be absent from the set.  Besides the performance benefit,
     191                 :            : there is also safety benefit since using set_add_entry() risks making
     192                 :            : a callback in the middle of a set_table_resize(), see issue 1456209.
     193                 :            : The caller is responsible for updating the key's reference count and
     194                 :            : the setobject's fill and used fields.
     195                 :            : */
     196                 :            : static void
     197                 :   12730803 : set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
     198                 :            : {
     199                 :            :     setentry *entry;
     200                 :   12730803 :     size_t perturb = hash;
     201                 :   12730803 :     size_t i = (size_t)hash & mask;
     202                 :            :     size_t j;
     203                 :            : 
     204                 :            :     while (1) {
     205                 :   13205489 :         entry = &table[i];
     206         [ +  + ]:   13205489 :         if (entry->key == NULL)
     207                 :   11867675 :             goto found_null;
     208         [ +  + ]:    1337814 :         if (i + LINEAR_PROBES <= mask) {
     209         [ +  + ]:    5222253 :             for (j = 0; j < LINEAR_PROBES; j++) {
     210                 :    4933010 :                 entry++;
     211         [ +  + ]:    4933010 :                 if (entry->key == NULL)
     212                 :     863128 :                     goto found_null;
     213                 :            :             }
     214                 :            :         }
     215                 :     474686 :         perturb >>= PERTURB_SHIFT;
     216                 :     474686 :         i = (i * 5 + 1 + perturb) & mask;
     217                 :            :     }
     218                 :   12730803 :   found_null:
     219                 :   12730803 :     entry->key = key;
     220                 :   12730803 :     entry->hash = hash;
     221                 :   12730803 : }
     222                 :            : 
     223                 :            : /* ======== End logic for probing the hash table ========================== */
     224                 :            : /* ======================================================================== */
     225                 :            : 
     226                 :            : /*
     227                 :            : Restructure the table by allocating a new table and reinserting all
     228                 :            : keys again.  When entries have been deleted, the new table may
     229                 :            : actually be smaller than the old one.
     230                 :            : */
     231                 :            : static int
     232                 :    1725945 : set_table_resize(PySetObject *so, Py_ssize_t minused)
     233                 :            : {
     234                 :            :     setentry *oldtable, *newtable, *entry;
     235                 :    1725945 :     Py_ssize_t oldmask = so->mask;
     236                 :            :     size_t newmask;
     237                 :            :     int is_oldtable_malloced;
     238                 :            :     setentry small_copy[PySet_MINSIZE];
     239                 :            : 
     240                 :            :     assert(minused >= 0);
     241                 :            : 
     242                 :            :     /* Find the smallest table size > minused. */
     243                 :            :     /* XXX speed-up with intrinsics */
     244                 :    1725945 :     size_t newsize = PySet_MINSIZE;
     245         [ +  + ]:    5367561 :     while (newsize <= (size_t)minused) {
     246                 :    3641616 :         newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
     247                 :            :     }
     248                 :            : 
     249                 :            :     /* Get space for a new table. */
     250                 :    1725945 :     oldtable = so->table;
     251                 :            :     assert(oldtable != NULL);
     252                 :    1725945 :     is_oldtable_malloced = oldtable != so->smalltable;
     253                 :            : 
     254         [ +  + ]:    1725945 :     if (newsize == PySet_MINSIZE) {
     255                 :            :         /* A large table is shrinking, or we can't get any smaller. */
     256                 :       1771 :         newtable = so->smalltable;
     257         [ +  + ]:       1771 :         if (newtable == oldtable) {
     258         [ -  + ]:       1536 :             if (so->fill == so->used) {
     259                 :            :                 /* No dummies, so no point doing anything. */
     260                 :          0 :                 return 0;
     261                 :            :             }
     262                 :            :             /* We're not going to resize it, but rebuild the
     263                 :            :                table anyway to purge old dummy entries.
     264                 :            :                Subtle:  This is *necessary* if fill==size,
     265                 :            :                as set_lookkey needs at least one virgin slot to
     266                 :            :                terminate failing searches.  If fill < size, it's
     267                 :            :                merely desirable, as dummies slow searches. */
     268                 :            :             assert(so->fill > so->used);
     269                 :       1536 :             memcpy(small_copy, oldtable, sizeof(small_copy));
     270                 :       1536 :             oldtable = small_copy;
     271                 :            :         }
     272                 :            :     }
     273                 :            :     else {
     274         [ +  - ]:    1724174 :         newtable = PyMem_NEW(setentry, newsize);
     275         [ -  + ]:    1724174 :         if (newtable == NULL) {
     276                 :            :             PyErr_NoMemory();
     277                 :          0 :             return -1;
     278                 :            :         }
     279                 :            :     }
     280                 :            : 
     281                 :            :     /* Make the set empty, using the new table. */
     282                 :            :     assert(newtable != oldtable);
     283                 :    1725945 :     memset(newtable, 0, sizeof(setentry) * newsize);
     284                 :    1725945 :     so->mask = newsize - 1;
     285                 :    1725945 :     so->table = newtable;
     286                 :            : 
     287                 :            :     /* Copy the data over; this is refcount-neutral for active entries;
     288                 :            :        dummy entries aren't copied over, of course */
     289                 :    1725945 :     newmask = (size_t)so->mask;
     290         [ +  + ]:    1725945 :     if (so->fill == so->used) {
     291         [ +  + ]:   22044531 :         for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
     292         [ +  + ]:   20321088 :             if (entry->key != NULL) {
     293                 :   11557338 :                 set_insert_clean(newtable, newmask, entry->key, entry->hash);
     294                 :            :             }
     295                 :            :         }
     296                 :            :     } else {
     297                 :       2502 :         so->fill = so->used;
     298         [ +  + ]:      68886 :         for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
     299   [ +  +  +  + ]:      66384 :             if (entry->key != NULL && entry->key != dummy) {
     300                 :       9612 :                 set_insert_clean(newtable, newmask, entry->key, entry->hash);
     301                 :            :             }
     302                 :            :         }
     303                 :            :     }
     304                 :            : 
     305         [ +  + ]:    1725945 :     if (is_oldtable_malloced)
     306                 :      90731 :         PyMem_Free(oldtable);
     307                 :    1725945 :     return 0;
     308                 :            : }
     309                 :            : 
     310                 :            : static int
     311                 :   38158871 : set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
     312                 :            : {
     313                 :            :     setentry *entry;
     314                 :            : 
     315                 :   38158871 :     entry = set_lookkey(so, key, hash);
     316         [ +  + ]:   38158871 :     if (entry != NULL)
     317                 :   38158867 :         return entry->key != NULL;
     318                 :          4 :     return -1;
     319                 :            : }
     320                 :            : 
     321                 :            : #define DISCARD_NOTFOUND 0
     322                 :            : #define DISCARD_FOUND 1
     323                 :            : 
     324                 :            : static int
     325                 :    1807885 : set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
     326                 :            : {
     327                 :            :     setentry *entry;
     328                 :            :     PyObject *old_key;
     329                 :            : 
     330                 :    1807885 :     entry = set_lookkey(so, key, hash);
     331         [ +  + ]:    1807885 :     if (entry == NULL)
     332                 :          4 :         return -1;
     333         [ +  + ]:    1807881 :     if (entry->key == NULL)
     334                 :    1650352 :         return DISCARD_NOTFOUND;
     335                 :     157529 :     old_key = entry->key;
     336                 :     157529 :     entry->key = dummy;
     337                 :     157529 :     entry->hash = -1;
     338                 :     157529 :     so->used--;
     339                 :     157529 :     Py_DECREF(old_key);
     340                 :     157529 :     return DISCARD_FOUND;
     341                 :            : }
     342                 :            : 
     343                 :            : static int
     344                 :   22789659 : set_add_key(PySetObject *so, PyObject *key)
     345                 :            : {
     346                 :            :     Py_hash_t hash;
     347                 :            : 
     348         [ +  + ]:   22789659 :     if (!PyUnicode_CheckExact(key) ||
     349         [ +  + ]:    7762866 :         (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
     350                 :   18643169 :         hash = PyObject_Hash(key);
     351         [ +  + ]:   18643169 :         if (hash == -1)
     352                 :         23 :             return -1;
     353                 :            :     }
     354                 :   22789636 :     return set_add_entry(so, key, hash);
     355                 :            : }
     356                 :            : 
     357                 :            : static int
     358                 :   36882032 : set_contains_key(PySetObject *so, PyObject *key)
     359                 :            : {
     360                 :            :     Py_hash_t hash;
     361                 :            : 
     362         [ +  + ]:   36882032 :     if (!PyUnicode_CheckExact(key) ||
     363         [ +  + ]:   32642323 :         (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
     364                 :   13371158 :         hash = PyObject_Hash(key);
     365         [ +  + ]:   13371158 :         if (hash == -1)
     366                 :         14 :             return -1;
     367                 :            :     }
     368                 :   36882018 :     return set_contains_entry(so, key, hash);
     369                 :            : }
     370                 :            : 
     371                 :            : static int
     372                 :    1744583 : set_discard_key(PySetObject *so, PyObject *key)
     373                 :            : {
     374                 :            :     Py_hash_t hash;
     375                 :            : 
     376         [ +  + ]:    1744583 :     if (!PyUnicode_CheckExact(key) ||
     377         [ +  + ]:    1621550 :         (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
     378                 :     125784 :         hash = PyObject_Hash(key);
     379         [ +  + ]:     125784 :         if (hash == -1)
     380                 :         20 :             return -1;
     381                 :            :     }
     382                 :    1744563 :     return set_discard_entry(so, key, hash);
     383                 :            : }
     384                 :            : 
     385                 :            : static void
     386                 :      53640 : set_empty_to_minsize(PySetObject *so)
     387                 :            : {
     388                 :      53640 :     memset(so->smalltable, 0, sizeof(so->smalltable));
     389                 :      53640 :     so->fill = 0;
     390                 :      53640 :     so->used = 0;
     391                 :      53640 :     so->mask = PySet_MINSIZE - 1;
     392                 :      53640 :     so->table = so->smalltable;
     393                 :      53640 :     so->hash = -1;
     394                 :      53640 : }
     395                 :            : 
     396                 :            : static int
     397                 :      57531 : set_clear_internal(PySetObject *so)
     398                 :            : {
     399                 :            :     setentry *entry;
     400                 :      57531 :     setentry *table = so->table;
     401                 :      57531 :     Py_ssize_t fill = so->fill;
     402                 :      57531 :     Py_ssize_t used = so->used;
     403                 :      57531 :     int table_is_malloced = table != so->smalltable;
     404                 :            :     setentry small_copy[PySet_MINSIZE];
     405                 :            : 
     406                 :            :     assert (PyAnySet_Check(so));
     407                 :            :     assert(table != NULL);
     408                 :            : 
     409                 :            :     /* This is delicate.  During the process of clearing the set,
     410                 :            :      * decrefs can cause the set to mutate.  To avoid fatal confusion
     411                 :            :      * (voice of experience), we have to make the set empty before
     412                 :            :      * clearing the slots, and never refer to anything via so->ref while
     413                 :            :      * clearing.
     414                 :            :      */
     415         [ +  + ]:      57531 :     if (table_is_malloced)
     416                 :      11926 :         set_empty_to_minsize(so);
     417                 :            : 
     418         [ +  + ]:      45605 :     else if (fill > 0) {
     419                 :            :         /* It's a small table with something that needs to be cleared.
     420                 :            :          * Afraid the only safe way is to copy the set entries into
     421                 :            :          * another small table first.
     422                 :            :          */
     423                 :      41714 :         memcpy(small_copy, table, sizeof(small_copy));
     424                 :      41714 :         table = small_copy;
     425                 :      41714 :         set_empty_to_minsize(so);
     426                 :            :     }
     427                 :            :     /* else it's a small table that's already empty */
     428                 :            : 
     429                 :            :     /* Now we can finally clear things.  If C had refcounts, we could
     430                 :            :      * assert that the refcount on table is 1 now, i.e. that this function
     431                 :            :      * has unique access to it, so decref side-effects can't alter it.
     432                 :            :      */
     433         [ +  + ]:     789675 :     for (entry = table; used > 0; entry++) {
     434   [ +  +  +  + ]:     732144 :         if (entry->key && entry->key != dummy) {
     435                 :     359817 :             used--;
     436                 :     359817 :             Py_DECREF(entry->key);
     437                 :            :         }
     438                 :            :     }
     439                 :            : 
     440         [ +  + ]:      57531 :     if (table_is_malloced)
     441                 :      11926 :         PyMem_Free(table);
     442                 :      57531 :     return 0;
     443                 :            : }
     444                 :            : 
     445                 :            : /*
     446                 :            :  * Iterate over a set table.  Use like so:
     447                 :            :  *
     448                 :            :  *     Py_ssize_t pos;
     449                 :            :  *     setentry *entry;
     450                 :            :  *     pos = 0;   # important!  pos should not otherwise be changed by you
     451                 :            :  *     while (set_next(yourset, &pos, &entry)) {
     452                 :            :  *              Refer to borrowed reference in entry->key.
     453                 :            :  *     }
     454                 :            :  *
     455                 :            :  * CAUTION:  In general, it isn't safe to use set_next in a loop that
     456                 :            :  * mutates the table.
     457                 :            :  */
     458                 :            : static int
     459                 :  109839916 : set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
     460                 :            : {
     461                 :            :     Py_ssize_t i;
     462                 :            :     Py_ssize_t mask;
     463                 :            :     setentry *entry;
     464                 :            : 
     465                 :            :     assert (PyAnySet_Check(so));
     466                 :  109839916 :     i = *pos_ptr;
     467                 :            :     assert(i >= 0);
     468                 :  109839916 :     mask = so->mask;
     469                 :  109839916 :     entry = &so->table[i];
     470   [ +  +  +  +  :  373160181 :     while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
                   +  + ]
     471                 :  263320265 :         i++;
     472                 :  263320265 :         entry++;
     473                 :            :     }
     474                 :  109839916 :     *pos_ptr = i+1;
     475         [ +  + ]:  109839916 :     if (i > mask)
     476                 :   10579259 :         return 0;
     477                 :            :     assert(entry != NULL);
     478                 :   99260657 :     *entry_ptr = entry;
     479                 :   99260657 :     return 1;
     480                 :            : }
     481                 :            : 
     482                 :            : static void
     483                 :    6282002 : set_dealloc(PySetObject *so)
     484                 :            : {
     485                 :            :     setentry *entry;
     486                 :    6282002 :     Py_ssize_t used = so->used;
     487                 :            : 
     488                 :            :     /* bpo-31095: UnTrack is needed before calling any callbacks */
     489                 :    6282002 :     PyObject_GC_UnTrack(so);
     490   [ +  +  +  + ]:    6282002 :     Py_TRASHCAN_BEGIN(so, set_dealloc)
     491         [ +  + ]:    6282000 :     if (so->weakreflist != NULL)
     492                 :        102 :         PyObject_ClearWeakRefs((PyObject *) so);
     493                 :            : 
     494         [ +  + ]:   73167741 :     for (entry = so->table; used > 0; entry++) {
     495   [ +  +  +  + ]:   66885741 :         if (entry->key && entry->key != dummy) {
     496                 :   24291422 :                 used--;
     497                 :   24291422 :                 Py_DECREF(entry->key);
     498                 :            :         }
     499                 :            :     }
     500         [ +  + ]:    6282000 :     if (so->table != so->smalltable)
     501                 :    1620997 :         PyMem_Free(so->table);
     502                 :    6282000 :     Py_TYPE(so)->tp_free(so);
     503         [ +  + ]:    6282000 :     Py_TRASHCAN_END
     504                 :    6282002 : }
     505                 :            : 
     506                 :            : static PyObject *
     507                 :       1204 : set_repr(PySetObject *so)
     508                 :            : {
     509                 :       1204 :     PyObject *result=NULL, *keys, *listrepr, *tmp;
     510                 :       1204 :     int status = Py_ReprEnter((PyObject*)so);
     511                 :            : 
     512         [ +  + ]:       1204 :     if (status != 0) {
     513         [ -  + ]:          7 :         if (status < 0)
     514                 :          0 :             return NULL;
     515                 :          7 :         return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
     516                 :            :     }
     517                 :            : 
     518                 :            :     /* shortcut for the empty set */
     519         [ +  + ]:       1197 :     if (!so->used) {
     520                 :        203 :         Py_ReprLeave((PyObject*)so);
     521                 :        203 :         return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
     522                 :            :     }
     523                 :            : 
     524                 :        994 :     keys = PySequence_List((PyObject *)so);
     525         [ -  + ]:        994 :     if (keys == NULL)
     526                 :          0 :         goto done;
     527                 :            : 
     528                 :            :     /* repr(keys)[1:-1] */
     529                 :        994 :     listrepr = PyObject_Repr(keys);
     530                 :        994 :     Py_DECREF(keys);
     531         [ -  + ]:        994 :     if (listrepr == NULL)
     532                 :          0 :         goto done;
     533                 :        994 :     tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
     534                 :        994 :     Py_DECREF(listrepr);
     535         [ -  + ]:        994 :     if (tmp == NULL)
     536                 :          0 :         goto done;
     537                 :        994 :     listrepr = tmp;
     538                 :            : 
     539         [ +  + ]:        994 :     if (!PySet_CheckExact(so))
     540                 :        677 :         result = PyUnicode_FromFormat("%s({%U})",
     541                 :        677 :                                       Py_TYPE(so)->tp_name,
     542                 :            :                                       listrepr);
     543                 :            :     else
     544                 :        317 :         result = PyUnicode_FromFormat("{%U}", listrepr);
     545                 :        994 :     Py_DECREF(listrepr);
     546                 :        994 : done:
     547                 :        994 :     Py_ReprLeave((PyObject*)so);
     548                 :        994 :     return result;
     549                 :            : }
     550                 :            : 
     551                 :            : static Py_ssize_t
     552                 :    1314617 : set_len(PyObject *so)
     553                 :            : {
     554                 :    1314617 :     return ((PySetObject *)so)->used;
     555                 :            : }
     556                 :            : 
     557                 :            : static int
     558                 :    3530331 : set_merge(PySetObject *so, PyObject *otherset)
     559                 :            : {
     560                 :            :     PySetObject *other;
     561                 :            :     PyObject *key;
     562                 :            :     Py_ssize_t i;
     563                 :            :     setentry *so_entry;
     564                 :            :     setentry *other_entry;
     565                 :            : 
     566                 :            :     assert (PyAnySet_Check(so));
     567                 :            :     assert (PyAnySet_Check(otherset));
     568                 :            : 
     569                 :    3530331 :     other = (PySetObject*)otherset;
     570   [ +  +  +  + ]:    3530331 :     if (other == so || other->used == 0)
     571                 :            :         /* a.update(a) or a.update(set()); nothing to do */
     572                 :    2586391 :         return 0;
     573                 :            :     /* Do one big resize at the start, rather than
     574                 :            :      * incrementally resizing as we insert new keys.  Expect
     575                 :            :      * that there will be no (or few) overlapping keys.
     576                 :            :      */
     577         [ +  + ]:     943940 :     if ((so->fill + other->used)*5 >= so->mask*3) {
     578         [ -  + ]:     213558 :         if (set_table_resize(so, (so->used + other->used)*2) != 0)
     579                 :          0 :             return -1;
     580                 :            :     }
     581                 :     943940 :     so_entry = so->table;
     582                 :     943940 :     other_entry = other->table;
     583                 :            : 
     584                 :            :     /* If our table is empty, and both tables have the same size, and
     585                 :            :        there are no dummies to eliminate, then just copy the pointers. */
     586   [ +  +  +  +  :     943940 :     if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
                   +  + ]
     587         [ +  + ]:    9263763 :         for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
     588                 :    8626280 :             key = other_entry->key;
     589         [ +  + ]:    8626280 :             if (key != NULL) {
     590                 :            :                 assert(so_entry->key == NULL);
     591                 :    2344884 :                 Py_INCREF(key);
     592                 :    2344884 :                 so_entry->key = key;
     593                 :    2344884 :                 so_entry->hash = other_entry->hash;
     594                 :            :             }
     595                 :            :         }
     596                 :     637483 :         so->fill = other->fill;
     597                 :     637483 :         so->used = other->used;
     598                 :     637483 :         return 0;
     599                 :            :     }
     600                 :            : 
     601                 :            :     /* If our table is empty, we can use set_insert_clean() */
     602         [ +  + ]:     306457 :     if (so->fill == 0) {
     603                 :      72240 :         setentry *newtable = so->table;
     604                 :      72240 :         size_t newmask = (size_t)so->mask;
     605                 :      72240 :         so->fill = other->used;
     606                 :      72240 :         so->used = other->used;
     607         [ +  + ]:    3664816 :         for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
     608                 :    3592576 :             key = other_entry->key;
     609   [ +  +  +  + ]:    3592576 :             if (key != NULL && key != dummy) {
     610                 :    1163853 :                 Py_INCREF(key);
     611                 :    1163853 :                 set_insert_clean(newtable, newmask, key, other_entry->hash);
     612                 :            :             }
     613                 :            :         }
     614                 :      72240 :         return 0;
     615                 :            :     }
     616                 :            : 
     617                 :            :     /* We can't assure there are no duplicates, so do normal insertions */
     618         [ +  + ]:    3097210 :     for (i = 0; i <= other->mask; i++) {
     619                 :    2862994 :         other_entry = &other->table[i];
     620                 :    2862994 :         key = other_entry->key;
     621   [ +  +  +  + ]:    2862994 :         if (key != NULL && key != dummy) {
     622         [ +  + ]:     698227 :             if (set_add_entry(so, key, other_entry->hash))
     623                 :          1 :                 return -1;
     624                 :            :         }
     625                 :            :     }
     626                 :     234216 :     return 0;
     627                 :            : }
     628                 :            : 
     629                 :            : static PyObject *
     630                 :      24362 : set_pop(PySetObject *so, PyObject *Py_UNUSED(ignored))
     631                 :            : {
     632                 :            :     /* Make sure the search finger is in bounds */
     633                 :      24362 :     setentry *entry = so->table + (so->finger & so->mask);
     634                 :      24362 :     setentry *limit = so->table + so->mask;
     635                 :            :     PyObject *key;
     636                 :            : 
     637         [ +  + ]:      24362 :     if (so->used == 0) {
     638                 :          3 :         PyErr_SetString(PyExc_KeyError, "pop from an empty set");
     639                 :          3 :         return NULL;
     640                 :            :     }
     641   [ +  +  -  + ]:     125553 :     while (entry->key == NULL || entry->key==dummy) {
     642                 :      76835 :         entry++;
     643         [ +  - ]:      76835 :         if (entry > limit)
     644                 :          0 :             entry = so->table;
     645                 :            :     }
     646                 :      24359 :     key = entry->key;
     647                 :      24359 :     entry->key = dummy;
     648                 :      24359 :     entry->hash = -1;
     649                 :      24359 :     so->used--;
     650                 :      24359 :     so->finger = entry - so->table + 1;   /* next place to start */
     651                 :      24359 :     return key;
     652                 :            : }
     653                 :            : 
     654                 :            : PyDoc_STRVAR(pop_doc, "Remove and return an arbitrary set element.\n\
     655                 :            : Raises KeyError if the set is empty.");
     656                 :            : 
     657                 :            : static int
     658                 :   10396936 : set_traverse(PySetObject *so, visitproc visit, void *arg)
     659                 :            : {
     660                 :   10396936 :     Py_ssize_t pos = 0;
     661                 :            :     setentry *entry;
     662                 :            : 
     663         [ +  + ]:  118670127 :     while (set_next(so, &pos, &entry))
     664   [ -  +  -  + ]:   97876255 :         Py_VISIT(entry->key);
     665                 :   10396936 :     return 0;
     666                 :            : }
     667                 :            : 
     668                 :            : /* Work to increase the bit dispersion for closely spaced hash values.
     669                 :            :    This is important because some use cases have many combinations of a
     670                 :            :    small number of elements with nearby hashes so that many distinct
     671                 :            :    combinations collapse to only a handful of distinct hash values. */
     672                 :            : 
     673                 :            : static Py_uhash_t
     674                 :   33594002 : _shuffle_bits(Py_uhash_t h)
     675                 :            : {
     676                 :   33594002 :     return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
     677                 :            : }
     678                 :            : 
     679                 :            : /* Most of the constants in this hash algorithm are randomly chosen
     680                 :            :    large primes with "interesting bit patterns" and that passed tests
     681                 :            :    for good collision statistics on a variety of problematic datasets
     682                 :            :    including powersets and graph structures (such as David Eppstein's
     683                 :            :    graph recipes in Lib/test/test_set.py) */
     684                 :            : 
     685                 :            : static Py_hash_t
     686                 :    5290311 : frozenset_hash(PyObject *self)
     687                 :            : {
     688                 :    5290311 :     PySetObject *so = (PySetObject *)self;
     689                 :    5290311 :     Py_uhash_t hash = 0;
     690                 :            :     setentry *entry;
     691                 :            : 
     692         [ +  + ]:    5290311 :     if (so->hash != -1)
     693                 :    4213319 :         return so->hash;
     694                 :            : 
     695                 :            :     /* Xor-in shuffled bits from every entry's hash field because xor is
     696                 :            :        commutative and a frozenset hash should be independent of order.
     697                 :            : 
     698                 :            :        For speed, include null entries and dummy entries and then
     699                 :            :        subtract out their effect afterwards so that the final hash
     700                 :            :        depends only on active entries.  This allows the code to be
     701                 :            :        vectorized by the compiler and it saves the unpredictable
     702                 :            :        branches that would arise when trying to exclude null and dummy
     703                 :            :        entries on every iteration. */
     704                 :            : 
     705         [ +  + ]:   34134784 :     for (entry = so->table; entry <= &so->table[so->mask]; entry++)
     706                 :   33057792 :         hash ^= _shuffle_bits(entry->hash);
     707                 :            : 
     708                 :            :     /* Remove the effect of an odd number of NULL entries */
     709         [ +  + ]:    1076992 :     if ((so->mask + 1 - so->fill) & 1)
     710                 :     536150 :         hash ^= _shuffle_bits(0);
     711                 :            : 
     712                 :            :     /* Remove the effect of an odd number of dummy entries */
     713         [ +  + ]:    1076992 :     if ((so->fill - so->used) & 1)
     714                 :         60 :         hash ^= _shuffle_bits(-1);
     715                 :            : 
     716                 :            :     /* Factor in the number of active entries */
     717                 :    1076992 :     hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;
     718                 :            : 
     719                 :            :     /* Disperse patterns arising in nested frozensets */
     720                 :    1076992 :     hash ^= (hash >> 11) ^ (hash >> 25);
     721                 :    1076992 :     hash = hash * 69069U + 907133923UL;
     722                 :            : 
     723                 :            :     /* -1 is reserved as an error code */
     724         [ -  + ]:    1076992 :     if (hash == (Py_uhash_t)-1)
     725                 :          0 :         hash = 590923713UL;
     726                 :            : 
     727                 :    1076992 :     so->hash = hash;
     728                 :    1076992 :     return hash;
     729                 :            : }
     730                 :            : 
     731                 :            : /***** Set iterator type ***********************************************/
     732                 :            : 
     733                 :            : typedef struct {
     734                 :            :     PyObject_HEAD
     735                 :            :     PySetObject *si_set; /* Set to NULL when iterator is exhausted */
     736                 :            :     Py_ssize_t si_used;
     737                 :            :     Py_ssize_t si_pos;
     738                 :            :     Py_ssize_t len;
     739                 :            : } setiterobject;
     740                 :            : 
     741                 :            : static void
     742                 :     770977 : setiter_dealloc(setiterobject *si)
     743                 :            : {
     744                 :            :     /* bpo-31095: UnTrack is needed before calling any callbacks */
     745                 :     770977 :     _PyObject_GC_UNTRACK(si);
     746                 :     770977 :     Py_XDECREF(si->si_set);
     747                 :     770977 :     PyObject_GC_Del(si);
     748                 :     770977 : }
     749                 :            : 
     750                 :            : static int
     751                 :        866 : setiter_traverse(setiterobject *si, visitproc visit, void *arg)
     752                 :            : {
     753   [ +  +  -  + ]:        866 :     Py_VISIT(si->si_set);
     754                 :        866 :     return 0;
     755                 :            : }
     756                 :            : 
     757                 :            : static PyObject *
     758                 :       8343 : setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
     759                 :            : {
     760                 :       8343 :     Py_ssize_t len = 0;
     761   [ +  +  +  + ]:       8343 :     if (si->si_set != NULL && si->si_used == si->si_set->used)
     762                 :       8341 :         len = si->len;
     763                 :       8343 :     return PyLong_FromSsize_t(len);
     764                 :            : }
     765                 :            : 
     766                 :            : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
     767                 :            : 
     768                 :            : static PyObject *setiter_iternext(setiterobject *si);
     769                 :            : 
     770                 :            : static PyObject *
     771                 :         24 : setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
     772                 :            : {
     773                 :            :     /* copy the iterator state */
     774                 :         24 :     setiterobject tmp = *si;
     775                 :         24 :     Py_XINCREF(tmp.si_set);
     776                 :            : 
     777                 :            :     /* iterate the temporary into a list */
     778                 :         24 :     PyObject *list = PySequence_List((PyObject*)&tmp);
     779                 :         24 :     Py_XDECREF(tmp.si_set);
     780         [ -  + ]:         24 :     if (list == NULL) {
     781                 :          0 :         return NULL;
     782                 :            :     }
     783                 :         24 :     return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
     784                 :            : }
     785                 :            : 
     786                 :            : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
     787                 :            : 
     788                 :            : static PyMethodDef setiter_methods[] = {
     789                 :            :     {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
     790                 :            :     {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
     791                 :            :     {NULL,              NULL}           /* sentinel */
     792                 :            : };
     793                 :            : 
     794                 :    2522201 : static PyObject *setiter_iternext(setiterobject *si)
     795                 :            : {
     796                 :            :     PyObject *key;
     797                 :            :     Py_ssize_t i, mask;
     798                 :            :     setentry *entry;
     799                 :    2522201 :     PySetObject *so = si->si_set;
     800                 :            : 
     801         [ +  + ]:    2522201 :     if (so == NULL)
     802                 :          4 :         return NULL;
     803                 :            :     assert (PyAnySet_Check(so));
     804                 :            : 
     805         [ +  + ]:    2522197 :     if (si->si_used != so->used) {
     806                 :          5 :         PyErr_SetString(PyExc_RuntimeError,
     807                 :            :                         "Set changed size during iteration");
     808                 :          5 :         si->si_used = -1; /* Make this state sticky */
     809                 :          5 :         return NULL;
     810                 :            :     }
     811                 :            : 
     812                 :    2522192 :     i = si->si_pos;
     813                 :            :     assert(i>=0);
     814                 :    2522192 :     entry = so->table;
     815                 :    2522192 :     mask = so->mask;
     816   [ +  +  +  +  :   12028643 :     while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy))
                   +  + ]
     817                 :    9506451 :         i++;
     818                 :    2522192 :     si->si_pos = i+1;
     819         [ +  + ]:    2522192 :     if (i > mask)
     820                 :     765988 :         goto fail;
     821                 :    1756204 :     si->len--;
     822                 :    1756204 :     key = entry[i].key;
     823                 :    1756204 :     Py_INCREF(key);
     824                 :    1756204 :     return key;
     825                 :            : 
     826                 :     765988 : fail:
     827                 :     765988 :     si->si_set = NULL;
     828                 :     765988 :     Py_DECREF(so);
     829                 :     765988 :     return NULL;
     830                 :            : }
     831                 :            : 
     832                 :            : PyTypeObject PySetIter_Type = {
     833                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
     834                 :            :     "set_iterator",                             /* tp_name */
     835                 :            :     sizeof(setiterobject),                      /* tp_basicsize */
     836                 :            :     0,                                          /* tp_itemsize */
     837                 :            :     /* methods */
     838                 :            :     (destructor)setiter_dealloc,                /* tp_dealloc */
     839                 :            :     0,                                          /* tp_vectorcall_offset */
     840                 :            :     0,                                          /* tp_getattr */
     841                 :            :     0,                                          /* tp_setattr */
     842                 :            :     0,                                          /* tp_as_async */
     843                 :            :     0,                                          /* tp_repr */
     844                 :            :     0,                                          /* tp_as_number */
     845                 :            :     0,                                          /* tp_as_sequence */
     846                 :            :     0,                                          /* tp_as_mapping */
     847                 :            :     0,                                          /* tp_hash */
     848                 :            :     0,                                          /* tp_call */
     849                 :            :     0,                                          /* tp_str */
     850                 :            :     PyObject_GenericGetAttr,                    /* tp_getattro */
     851                 :            :     0,                                          /* tp_setattro */
     852                 :            :     0,                                          /* tp_as_buffer */
     853                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
     854                 :            :     0,                                          /* tp_doc */
     855                 :            :     (traverseproc)setiter_traverse,             /* tp_traverse */
     856                 :            :     0,                                          /* tp_clear */
     857                 :            :     0,                                          /* tp_richcompare */
     858                 :            :     0,                                          /* tp_weaklistoffset */
     859                 :            :     PyObject_SelfIter,                          /* tp_iter */
     860                 :            :     (iternextfunc)setiter_iternext,             /* tp_iternext */
     861                 :            :     setiter_methods,                            /* tp_methods */
     862                 :            :     0,
     863                 :            : };
     864                 :            : 
     865                 :            : static PyObject *
     866                 :     770977 : set_iter(PySetObject *so)
     867                 :            : {
     868                 :     770977 :     setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
     869         [ -  + ]:     770977 :     if (si == NULL)
     870                 :          0 :         return NULL;
     871                 :     770977 :     Py_INCREF(so);
     872                 :     770977 :     si->si_set = so;
     873                 :     770977 :     si->si_used = so->used;
     874                 :     770977 :     si->si_pos = 0;
     875                 :     770977 :     si->len = so->used;
     876                 :     770977 :     _PyObject_GC_TRACK(si);
     877                 :     770977 :     return (PyObject *)si;
     878                 :            : }
     879                 :            : 
     880                 :            : static int
     881                 :    5325916 : set_update_internal(PySetObject *so, PyObject *other)
     882                 :            : {
     883                 :            :     PyObject *key, *it;
     884                 :            : 
     885   [ +  +  +  +  :    5325916 :     if (PyAnySet_Check(other))
             +  +  +  + ]
     886                 :    3530331 :         return set_merge(so, other);
     887                 :            : 
     888         [ +  + ]:    1795585 :     if (PyDict_CheckExact(other)) {
     889                 :            :         PyObject *value;
     890                 :      23068 :         Py_ssize_t pos = 0;
     891                 :            :         Py_hash_t hash;
     892                 :      23068 :         Py_ssize_t dictsize = PyDict_GET_SIZE(other);
     893                 :            : 
     894                 :            :         /* Do one big resize at the start, rather than
     895                 :            :         * incrementally resizing as we insert new keys.  Expect
     896                 :            :         * that there will be no (or few) overlapping keys.
     897                 :            :         */
     898         [ -  + ]:      23068 :         if (dictsize < 0)
     899                 :          0 :             return -1;
     900         [ +  + ]:      23068 :         if ((so->fill + dictsize)*5 >= so->mask*3) {
     901         [ -  + ]:       3056 :             if (set_table_resize(so, (so->used + dictsize)*2) != 0)
     902                 :          0 :                 return -1;
     903                 :            :         }
     904         [ +  + ]:      70451 :         while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
     905         [ -  + ]:      47383 :             if (set_add_entry(so, key, hash))
     906                 :          0 :                 return -1;
     907                 :            :         }
     908                 :      23068 :         return 0;
     909                 :            :     }
     910                 :            : 
     911                 :    1772517 :     it = PyObject_GetIter(other);
     912         [ +  + ]:    1772517 :     if (it == NULL)
     913                 :         83 :         return -1;
     914                 :            : 
     915         [ +  + ]:   19320748 :     while ((key = PyIter_Next(it)) != NULL) {
     916         [ +  + ]:   17548338 :         if (set_add_key(so, key)) {
     917                 :         24 :             Py_DECREF(it);
     918                 :         24 :             Py_DECREF(key);
     919                 :         24 :             return -1;
     920                 :            :         }
     921                 :   17548314 :         Py_DECREF(key);
     922                 :            :     }
     923                 :    1772410 :     Py_DECREF(it);
     924         [ +  + ]:    1772410 :     if (PyErr_Occurred())
     925                 :         55 :         return -1;
     926                 :    1772355 :     return 0;
     927                 :            : }
     928                 :            : 
     929                 :            : static PyObject *
     930                 :       3461 : set_update(PySetObject *so, PyObject *args)
     931                 :            : {
     932                 :            :     Py_ssize_t i;
     933                 :            : 
     934         [ +  + ]:       6957 :     for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
     935                 :       3521 :         PyObject *other = PyTuple_GET_ITEM(args, i);
     936         [ +  + ]:       3521 :         if (set_update_internal(so, other))
     937                 :         25 :             return NULL;
     938                 :            :     }
     939                 :       3436 :     Py_RETURN_NONE;
     940                 :            : }
     941                 :            : 
     942                 :            : PyDoc_STRVAR(update_doc,
     943                 :            : "Update a set with the union of itself and others.");
     944                 :            : 
     945                 :            : /* XXX Todo:
     946                 :            :    If aligned memory allocations become available, make the
     947                 :            :    set object 64 byte aligned so that most of the fields
     948                 :            :    can be retrieved or updated in a single cache line.
     949                 :            : */
     950                 :            : 
     951                 :            : static PyObject *
     952                 :    6285690 : make_new_set(PyTypeObject *type, PyObject *iterable)
     953                 :            : {
     954                 :            :     assert(PyType_Check(type));
     955                 :            :     PySetObject *so;
     956                 :            : 
     957                 :    6285690 :     so = (PySetObject *)type->tp_alloc(type, 0);
     958         [ +  + ]:    6285690 :     if (so == NULL)
     959                 :         34 :         return NULL;
     960                 :            : 
     961                 :    6285656 :     so->fill = 0;
     962                 :    6285656 :     so->used = 0;
     963                 :    6285656 :     so->mask = PySet_MINSIZE - 1;
     964                 :    6285656 :     so->table = so->smalltable;
     965                 :    6285656 :     so->hash = -1;
     966                 :    6285656 :     so->finger = 0;
     967                 :    6285656 :     so->weakreflist = NULL;
     968                 :            : 
     969         [ +  + ]:    6285656 :     if (iterable != NULL) {
     970         [ +  + ]:    2876815 :         if (set_update_internal(so, iterable)) {
     971                 :        102 :             Py_DECREF(so);
     972                 :        102 :             return NULL;
     973                 :            :         }
     974                 :            :     }
     975                 :            : 
     976                 :    6285554 :     return (PyObject *)so;
     977                 :            : }
     978                 :            : 
     979                 :            : static PyObject *
     980                 :     127448 : make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
     981                 :            : {
     982   [ +  +  +  + ]:     127448 :     if (type != &PySet_Type && type != &PyFrozenSet_Type) {
     983         [ +  + ]:       2393 :         if (PyType_IsSubtype(type, &PySet_Type))
     984                 :       2240 :             type = &PySet_Type;
     985                 :            :         else
     986                 :        153 :             type = &PyFrozenSet_Type;
     987                 :            :     }
     988                 :     127448 :     return make_new_set(type, iterable);
     989                 :            : }
     990                 :            : 
     991                 :            : static PyObject *
     992                 :    1105018 : make_new_frozenset(PyTypeObject *type, PyObject *iterable)
     993                 :            : {
     994         [ +  + ]:    1105018 :     if (type != &PyFrozenSet_Type) {
     995                 :        744 :         return make_new_set(type, iterable);
     996                 :            :     }
     997                 :            : 
     998   [ +  +  +  + ]:    1104274 :     if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
     999                 :            :         /* frozenset(f) is idempotent */
    1000                 :         33 :         Py_INCREF(iterable);
    1001                 :         33 :         return iterable;
    1002                 :            :     }
    1003                 :    1104241 :     return make_new_set(type, iterable);
    1004                 :            : }
    1005                 :            : 
    1006                 :            : static PyObject *
    1007                 :        746 : frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    1008                 :            : {
    1009                 :        746 :     PyObject *iterable = NULL;
    1010                 :            : 
    1011         [ +  - ]:        746 :     if ((type == &PyFrozenSet_Type ||
    1012   [ +  +  +  + ]:        746 :          type->tp_init == PyFrozenSet_Type.tp_init) &&
    1013         [ +  + ]:          5 :         !_PyArg_NoKeywords("frozenset", kwds)) {
    1014                 :          1 :         return NULL;
    1015                 :            :     }
    1016                 :            : 
    1017         [ +  + ]:        745 :     if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
    1018                 :          1 :         return NULL;
    1019                 :            :     }
    1020                 :            : 
    1021                 :        744 :     return make_new_frozenset(type, iterable);
    1022                 :            : }
    1023                 :            : 
    1024                 :            : static PyObject *
    1025                 :    1104275 : frozenset_vectorcall(PyObject *type, PyObject * const*args,
    1026                 :            :                      size_t nargsf, PyObject *kwnames)
    1027                 :            : {
    1028   [ -  +  -  - ]:    1104275 :     if (!_PyArg_NoKwnames("frozenset", kwnames)) {
    1029                 :          0 :         return NULL;
    1030                 :            :     }
    1031                 :            : 
    1032                 :    1104275 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    1033   [ +  -  +  +  :    1104275 :     if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
                   +  - ]
    1034                 :          1 :         return NULL;
    1035                 :            :     }
    1036                 :            : 
    1037         [ +  + ]:    1104274 :     PyObject *iterable = (nargs ? args[0] : NULL);
    1038                 :    1104274 :     return make_new_frozenset(_PyType_CAST(type), iterable);
    1039                 :            : }
    1040                 :            : 
    1041                 :            : static PyObject *
    1042                 :      12235 : set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    1043                 :            : {
    1044                 :      12235 :     return make_new_set(type, NULL);
    1045                 :            : }
    1046                 :            : 
    1047                 :            : /* set_swap_bodies() switches the contents of any two sets by moving their
    1048                 :            :    internal data pointers and, if needed, copying the internal smalltables.
    1049                 :            :    Semantically equivalent to:
    1050                 :            : 
    1051                 :            :      t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t
    1052                 :            : 
    1053                 :            :    The function always succeeds and it leaves both objects in a stable state.
    1054                 :            :    Useful for operations that update in-place (by allowing an intermediate
    1055                 :            :    result to be swapped into one of the original inputs).
    1056                 :            : */
    1057                 :            : 
    1058                 :            : static void
    1059                 :       1145 : set_swap_bodies(PySetObject *a, PySetObject *b)
    1060                 :            : {
    1061                 :            :     Py_ssize_t t;
    1062                 :            :     setentry *u;
    1063                 :            :     setentry tab[PySet_MINSIZE];
    1064                 :            :     Py_hash_t h;
    1065                 :            : 
    1066                 :       1145 :     t = a->fill;     a->fill   = b->fill;        b->fill  = t;
    1067                 :       1145 :     t = a->used;     a->used   = b->used;        b->used  = t;
    1068                 :       1145 :     t = a->mask;     a->mask   = b->mask;        b->mask  = t;
    1069                 :            : 
    1070                 :       1145 :     u = a->table;
    1071         [ +  + ]:       1145 :     if (a->table == a->smalltable)
    1072                 :        621 :         u = b->smalltable;
    1073                 :       1145 :     a->table  = b->table;
    1074         [ +  + ]:       1145 :     if (b->table == b->smalltable)
    1075                 :       1073 :         a->table = a->smalltable;
    1076                 :       1145 :     b->table = u;
    1077                 :            : 
    1078   [ +  +  +  + ]:       1145 :     if (a->table == a->smalltable || b->table == b->smalltable) {
    1079                 :       1108 :         memcpy(tab, a->smalltable, sizeof(tab));
    1080                 :       1108 :         memcpy(a->smalltable, b->smalltable, sizeof(tab));
    1081                 :       1108 :         memcpy(b->smalltable, tab, sizeof(tab));
    1082                 :            :     }
    1083                 :            : 
    1084   [ -  +  -  - ]:       1145 :     if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type)  &&
    1085                 :          0 :         PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
    1086                 :          0 :         h = a->hash;     a->hash = b->hash;  b->hash = h;
    1087                 :            :     } else {
    1088                 :       1145 :         a->hash = -1;
    1089                 :       1145 :         b->hash = -1;
    1090                 :            :     }
    1091                 :       1145 : }
    1092                 :            : 
    1093                 :            : static PyObject *
    1094                 :      34732 : set_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
    1095                 :            : {
    1096                 :      34732 :     return make_new_set_basetype(Py_TYPE(so), (PyObject *)so);
    1097                 :            : }
    1098                 :            : 
    1099                 :            : static PyObject *
    1100                 :          2 : frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored))
    1101                 :            : {
    1102         [ +  + ]:          2 :     if (PyFrozenSet_CheckExact(so)) {
    1103                 :          1 :         Py_INCREF(so);
    1104                 :          1 :         return (PyObject *)so;
    1105                 :            :     }
    1106                 :          1 :     return set_copy(so, NULL);
    1107                 :            : }
    1108                 :            : 
    1109                 :            : PyDoc_STRVAR(copy_doc, "Return a shallow copy of a set.");
    1110                 :            : 
    1111                 :            : static PyObject *
    1112                 :      12273 : set_clear(PySetObject *so, PyObject *Py_UNUSED(ignored))
    1113                 :            : {
    1114                 :      12273 :     set_clear_internal(so);
    1115                 :      12273 :     Py_RETURN_NONE;
    1116                 :            : }
    1117                 :            : 
    1118                 :            : PyDoc_STRVAR(clear_doc, "Remove all elements from this set.");
    1119                 :            : 
    1120                 :            : static PyObject *
    1121                 :       1297 : set_union(PySetObject *so, PyObject *args)
    1122                 :            : {
    1123                 :            :     PySetObject *result;
    1124                 :            :     PyObject *other;
    1125                 :            :     Py_ssize_t i;
    1126                 :            : 
    1127                 :       1297 :     result = (PySetObject *)set_copy(so, NULL);
    1128         [ -  + ]:       1297 :     if (result == NULL)
    1129                 :          0 :         return NULL;
    1130                 :            : 
    1131         [ +  + ]:       2617 :     for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
    1132                 :       1348 :         other = PyTuple_GET_ITEM(args, i);
    1133         [ +  + ]:       1348 :         if ((PyObject *)so == other)
    1134                 :          5 :             continue;
    1135         [ +  + ]:       1343 :         if (set_update_internal(result, other)) {
    1136                 :         28 :             Py_DECREF(result);
    1137                 :         28 :             return NULL;
    1138                 :            :         }
    1139                 :            :     }
    1140                 :       1269 :     return (PyObject *)result;
    1141                 :            : }
    1142                 :            : 
    1143                 :            : PyDoc_STRVAR(union_doc,
    1144                 :            :  "Return the union of sets as a new set.\n\
    1145                 :            : \n\
    1146                 :            : (i.e. all elements that are in either set.)");
    1147                 :            : 
    1148                 :            : static PyObject *
    1149                 :      27290 : set_or(PySetObject *so, PyObject *other)
    1150                 :            : {
    1151                 :            :     PySetObject *result;
    1152                 :            : 
    1153   [ +  +  +  +  :      27290 :     if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
          +  +  +  +  +  
          +  +  +  +  +  
                   +  - ]
    1154                 :         25 :         Py_RETURN_NOTIMPLEMENTED;
    1155                 :            : 
    1156                 :      27265 :     result = (PySetObject *)set_copy(so, NULL);
    1157         [ -  + ]:      27265 :     if (result == NULL)
    1158                 :          0 :         return NULL;
    1159         [ +  + ]:      27265 :     if ((PyObject *)so == other)
    1160                 :          7 :         return (PyObject *)result;
    1161         [ -  + ]:      27258 :     if (set_update_internal(result, other)) {
    1162                 :          0 :         Py_DECREF(result);
    1163                 :          0 :         return NULL;
    1164                 :            :     }
    1165                 :      27258 :     return (PyObject *)result;
    1166                 :            : }
    1167                 :            : 
    1168                 :            : static PyObject *
    1169                 :    2398129 : set_ior(PySetObject *so, PyObject *other)
    1170                 :            : {
    1171   [ +  +  +  -  :    2398129 :     if (!PyAnySet_Check(other))
             +  +  +  - ]
    1172                 :          6 :         Py_RETURN_NOTIMPLEMENTED;
    1173                 :            : 
    1174         [ -  + ]:    2398123 :     if (set_update_internal(so, other))
    1175                 :          0 :         return NULL;
    1176                 :    2398123 :     Py_INCREF(so);
    1177                 :    2398123 :     return (PyObject *)so;
    1178                 :            : }
    1179                 :            : 
    1180                 :            : static PyObject *
    1181                 :      38147 : set_intersection(PySetObject *so, PyObject *other)
    1182                 :            : {
    1183                 :            :     PySetObject *result;
    1184                 :            :     PyObject *key, *it, *tmp;
    1185                 :            :     Py_hash_t hash;
    1186                 :            :     int rv;
    1187                 :            : 
    1188         [ +  + ]:      38147 :     if ((PyObject *)so == other)
    1189                 :          9 :         return set_copy(so, NULL);
    1190                 :            : 
    1191                 :      38138 :     result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
    1192         [ -  + ]:      38138 :     if (result == NULL)
    1193                 :          0 :         return NULL;
    1194                 :            : 
    1195   [ +  +  +  +  :      38138 :     if (PyAnySet_Check(other)) {
             +  +  -  + ]
    1196                 :      34490 :         Py_ssize_t pos = 0;
    1197                 :            :         setentry *entry;
    1198                 :            : 
    1199         [ +  + ]:      34490 :         if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
    1200                 :      16747 :             tmp = (PyObject *)so;
    1201                 :      16747 :             so = (PySetObject *)other;
    1202                 :      16747 :             other = tmp;
    1203                 :            :         }
    1204                 :            : 
    1205         [ +  + ]:      87351 :         while (set_next((PySetObject *)other, &pos, &entry)) {
    1206                 :      52861 :             key = entry->key;
    1207                 :      52861 :             hash = entry->hash;
    1208                 :      52861 :             Py_INCREF(key);
    1209                 :      52861 :             rv = set_contains_entry(so, key, hash);
    1210         [ -  + ]:      52861 :             if (rv < 0) {
    1211                 :          0 :                 Py_DECREF(result);
    1212                 :          0 :                 Py_DECREF(key);
    1213                 :          0 :                 return NULL;
    1214                 :            :             }
    1215         [ +  + ]:      52861 :             if (rv) {
    1216         [ -  + ]:       9633 :                 if (set_add_entry(result, key, hash)) {
    1217                 :          0 :                     Py_DECREF(result);
    1218                 :          0 :                     Py_DECREF(key);
    1219                 :          0 :                     return NULL;
    1220                 :            :                 }
    1221                 :            :             }
    1222                 :      52861 :             Py_DECREF(key);
    1223                 :            :         }
    1224                 :      34490 :         return (PyObject *)result;
    1225                 :            :     }
    1226                 :            : 
    1227                 :       3648 :     it = PyObject_GetIter(other);
    1228         [ +  + ]:       3648 :     if (it == NULL) {
    1229                 :         28 :         Py_DECREF(result);
    1230                 :         28 :         return NULL;
    1231                 :            :     }
    1232                 :            : 
    1233         [ +  + ]:      81267 :     while ((key = PyIter_Next(it)) != NULL) {
    1234                 :      78136 :         hash = PyObject_Hash(key);
    1235         [ +  + ]:      78136 :         if (hash == -1)
    1236                 :          2 :             goto error;
    1237                 :      78134 :         rv = set_contains_entry(so, key, hash);
    1238         [ -  + ]:      78134 :         if (rv < 0)
    1239                 :          0 :             goto error;
    1240         [ +  + ]:      78134 :         if (rv) {
    1241         [ -  + ]:      15571 :             if (set_add_entry(result, key, hash))
    1242                 :          0 :                 goto error;
    1243         [ +  + ]:      15571 :             if (PySet_GET_SIZE(result) >= PySet_GET_SIZE(so)) {
    1244                 :        487 :                 Py_DECREF(key);
    1245                 :        487 :                 break;
    1246                 :            :             }
    1247                 :            :         }
    1248                 :      77647 :         Py_DECREF(key);
    1249                 :            :     }
    1250                 :       3618 :     Py_DECREF(it);
    1251         [ +  + ]:       3618 :     if (PyErr_Occurred()) {
    1252                 :        146 :         Py_DECREF(result);
    1253                 :        146 :         return NULL;
    1254                 :            :     }
    1255                 :       3472 :     return (PyObject *)result;
    1256                 :          2 :   error:
    1257                 :          2 :     Py_DECREF(it);
    1258                 :          2 :     Py_DECREF(result);
    1259                 :          2 :     Py_DECREF(key);
    1260                 :          2 :     return NULL;
    1261                 :            : }
    1262                 :            : 
    1263                 :            : static PyObject *
    1264                 :       5074 : set_intersection_multi(PySetObject *so, PyObject *args)
    1265                 :            : {
    1266                 :            :     Py_ssize_t i;
    1267                 :       5074 :     PyObject *result = (PyObject *)so;
    1268                 :            : 
    1269         [ +  + ]:       5074 :     if (PyTuple_GET_SIZE(args) == 0)
    1270                 :          4 :         return set_copy(so, NULL);
    1271                 :            : 
    1272                 :       5070 :     Py_INCREF(so);
    1273         [ +  + ]:      10080 :     for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
    1274                 :       5142 :         PyObject *other = PyTuple_GET_ITEM(args, i);
    1275                 :       5142 :         PyObject *newresult = set_intersection((PySetObject *)result, other);
    1276         [ +  + ]:       5142 :         if (newresult == NULL) {
    1277                 :        132 :             Py_DECREF(result);
    1278                 :        132 :             return NULL;
    1279                 :            :         }
    1280                 :       5010 :         Py_DECREF(result);
    1281                 :       5010 :         result = newresult;
    1282                 :            :     }
    1283                 :       4938 :     return result;
    1284                 :            : }
    1285                 :            : 
    1286                 :            : PyDoc_STRVAR(intersection_doc,
    1287                 :            : "Return the intersection of two sets as a new set.\n\
    1288                 :            : \n\
    1289                 :            : (i.e. all elements that are in both sets.)");
    1290                 :            : 
    1291                 :            : static PyObject *
    1292                 :        408 : set_intersection_update(PySetObject *so, PyObject *other)
    1293                 :            : {
    1294                 :            :     PyObject *tmp;
    1295                 :            : 
    1296                 :        408 :     tmp = set_intersection(so, other);
    1297         [ -  + ]:        408 :     if (tmp == NULL)
    1298                 :          0 :         return NULL;
    1299                 :        408 :     set_swap_bodies(so, (PySetObject *)tmp);
    1300                 :        408 :     Py_DECREF(tmp);
    1301                 :        408 :     Py_RETURN_NONE;
    1302                 :            : }
    1303                 :            : 
    1304                 :            : static PyObject *
    1305                 :        803 : set_intersection_update_multi(PySetObject *so, PyObject *args)
    1306                 :            : {
    1307                 :            :     PyObject *tmp;
    1308                 :            : 
    1309                 :        803 :     tmp = set_intersection_multi(so, args);
    1310         [ +  + ]:        803 :     if (tmp == NULL)
    1311                 :         66 :         return NULL;
    1312                 :        737 :     set_swap_bodies(so, (PySetObject *)tmp);
    1313                 :        737 :     Py_DECREF(tmp);
    1314                 :        737 :     Py_RETURN_NONE;
    1315                 :            : }
    1316                 :            : 
    1317                 :            : PyDoc_STRVAR(intersection_update_doc,
    1318                 :            : "Update a set with the intersection of itself and another.");
    1319                 :            : 
    1320                 :            : static PyObject *
    1321                 :      32371 : set_and(PySetObject *so, PyObject *other)
    1322                 :            : {
    1323   [ +  +  +  +  :      32371 :     if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
          +  +  +  +  +  
          +  +  +  +  +  
                   +  - ]
    1324                 :         24 :         Py_RETURN_NOTIMPLEMENTED;
    1325                 :      32347 :     return set_intersection(so, other);
    1326                 :            : }
    1327                 :            : 
    1328                 :            : static PyObject *
    1329                 :        414 : set_iand(PySetObject *so, PyObject *other)
    1330                 :            : {
    1331                 :            :     PyObject *result;
    1332                 :            : 
    1333   [ +  +  +  -  :        414 :     if (!PyAnySet_Check(other))
             +  +  +  - ]
    1334                 :          6 :         Py_RETURN_NOTIMPLEMENTED;
    1335                 :        408 :     result = set_intersection_update(so, other);
    1336         [ -  + ]:        408 :     if (result == NULL)
    1337                 :          0 :         return NULL;
    1338                 :        408 :     Py_DECREF(result);
    1339                 :        408 :     Py_INCREF(so);
    1340                 :        408 :     return (PyObject *)so;
    1341                 :            : }
    1342                 :            : 
    1343                 :            : static PyObject *
    1344                 :       4073 : set_isdisjoint(PySetObject *so, PyObject *other)
    1345                 :            : {
    1346                 :            :     PyObject *key, *it, *tmp;
    1347                 :            :     int rv;
    1348                 :            : 
    1349         [ +  + ]:       4073 :     if ((PyObject *)so == other) {
    1350         [ +  + ]:          7 :         if (PySet_GET_SIZE(so) == 0)
    1351                 :          1 :             Py_RETURN_TRUE;
    1352                 :            :         else
    1353                 :          6 :             Py_RETURN_FALSE;
    1354                 :            :     }
    1355                 :            : 
    1356   [ +  +  +  + ]:       4066 :     if (PyAnySet_CheckExact(other)) {
    1357                 :       1018 :         Py_ssize_t pos = 0;
    1358                 :            :         setentry *entry;
    1359                 :            : 
    1360         [ +  + ]:       1018 :         if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
    1361                 :        381 :             tmp = (PyObject *)so;
    1362                 :        381 :             so = (PySetObject *)other;
    1363                 :        381 :             other = tmp;
    1364                 :            :         }
    1365         [ +  + ]:       1906 :         while (set_next((PySetObject *)other, &pos, &entry)) {
    1366                 :       1408 :             PyObject *key = entry->key;
    1367                 :       1408 :             Py_INCREF(key);
    1368                 :       1408 :             rv = set_contains_entry(so, key, entry->hash);
    1369                 :       1408 :             Py_DECREF(key);
    1370         [ -  + ]:       1408 :             if (rv < 0) {
    1371                 :          0 :                 return NULL;
    1372                 :            :             }
    1373         [ +  + ]:       1408 :             if (rv) {
    1374                 :        520 :                 Py_RETURN_FALSE;
    1375                 :            :             }
    1376                 :            :         }
    1377                 :        498 :         Py_RETURN_TRUE;
    1378                 :            :     }
    1379                 :            : 
    1380                 :       3048 :     it = PyObject_GetIter(other);
    1381         [ +  + ]:       3048 :     if (it == NULL)
    1382                 :         12 :         return NULL;
    1383                 :            : 
    1384         [ +  + ]:      27706 :     while ((key = PyIter_Next(it)) != NULL) {
    1385                 :      25836 :         rv = set_contains_key(so, key);
    1386                 :      25836 :         Py_DECREF(key);
    1387         [ -  + ]:      25836 :         if (rv < 0) {
    1388                 :          0 :             Py_DECREF(it);
    1389                 :          0 :             return NULL;
    1390                 :            :         }
    1391         [ +  + ]:      25836 :         if (rv) {
    1392                 :       1166 :             Py_DECREF(it);
    1393                 :       1166 :             Py_RETURN_FALSE;
    1394                 :            :         }
    1395                 :            :     }
    1396                 :       1870 :     Py_DECREF(it);
    1397         [ +  + ]:       1870 :     if (PyErr_Occurred())
    1398                 :         10 :         return NULL;
    1399                 :       1860 :     Py_RETURN_TRUE;
    1400                 :            : }
    1401                 :            : 
    1402                 :            : PyDoc_STRVAR(isdisjoint_doc,
    1403                 :            : "Return True if two sets have a null intersection.");
    1404                 :            : 
    1405                 :            : static int
    1406                 :      20166 : set_difference_update_internal(PySetObject *so, PyObject *other)
    1407                 :            : {
    1408         [ +  + ]:      20166 :     if ((PyObject *)so == other)
    1409                 :          2 :         return set_clear_internal(so);
    1410                 :            : 
    1411   [ +  +  +  +  :      26786 :     if (PyAnySet_Check(other)) {
             +  +  -  + ]
    1412                 :            :         setentry *entry;
    1413                 :       6622 :         Py_ssize_t pos = 0;
    1414                 :            : 
    1415                 :            :         /* Optimization:  When the other set is more than 8 times
    1416                 :            :            larger than the base set, replace the other set with
    1417                 :            :            intersection of the two sets.
    1418                 :            :         */
    1419         [ +  + ]:       6622 :         if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
    1420                 :         37 :             other = set_intersection(so, other);
    1421         [ -  + ]:         37 :             if (other == NULL)
    1422                 :          0 :                 return -1;
    1423                 :            :         } else {
    1424                 :       6585 :             Py_INCREF(other);
    1425                 :            :         }
    1426                 :            : 
    1427         [ +  + ]:      38273 :         while (set_next((PySetObject *)other, &pos, &entry)) {
    1428                 :      31651 :             PyObject *key = entry->key;
    1429                 :      31651 :             Py_INCREF(key);
    1430         [ -  + ]:      31651 :             if (set_discard_entry(so, key, entry->hash) < 0) {
    1431                 :          0 :                 Py_DECREF(other);
    1432                 :          0 :                 Py_DECREF(key);
    1433                 :          0 :                 return -1;
    1434                 :            :             }
    1435                 :      31651 :             Py_DECREF(key);
    1436                 :            :         }
    1437                 :            : 
    1438                 :       6622 :         Py_DECREF(other);
    1439                 :            :     } else {
    1440                 :            :         PyObject *key, *it;
    1441                 :      13542 :         it = PyObject_GetIter(other);
    1442         [ +  + ]:      13542 :         if (it == NULL)
    1443                 :         45 :             return -1;
    1444                 :            : 
    1445         [ +  + ]:      46375 :         while ((key = PyIter_Next(it)) != NULL) {
    1446         [ +  + ]:      32884 :             if (set_discard_key(so, key) < 0) {
    1447                 :          6 :                 Py_DECREF(it);
    1448                 :          6 :                 Py_DECREF(key);
    1449                 :          6 :                 return -1;
    1450                 :            :             }
    1451                 :      32878 :             Py_DECREF(key);
    1452                 :            :         }
    1453                 :      13491 :         Py_DECREF(it);
    1454         [ +  + ]:      13491 :         if (PyErr_Occurred())
    1455                 :         67 :             return -1;
    1456                 :            :     }
    1457                 :            :     /* If more than 1/4th are dummies, then resize them away. */
    1458         [ +  + ]:      20046 :     if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
    1459                 :      18294 :         return 0;
    1460         [ -  + ]:       1752 :     return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
    1461                 :            : }
    1462                 :            : 
    1463                 :            : static PyObject *
    1464                 :      13784 : set_difference_update(PySetObject *so, PyObject *args)
    1465                 :            : {
    1466                 :            :     Py_ssize_t i;
    1467                 :            : 
    1468         [ +  + ]:      27490 :     for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
    1469                 :      13784 :         PyObject *other = PyTuple_GET_ITEM(args, i);
    1470         [ +  + ]:      13784 :         if (set_difference_update_internal(so, other))
    1471                 :         78 :             return NULL;
    1472                 :            :     }
    1473                 :      13706 :     Py_RETURN_NONE;
    1474                 :            : }
    1475                 :            : 
    1476                 :            : PyDoc_STRVAR(difference_update_doc,
    1477                 :            : "Remove all elements of another set from this set.");
    1478                 :            : 
    1479                 :            : static PyObject *
    1480                 :       5898 : set_copy_and_difference(PySetObject *so, PyObject *other)
    1481                 :            : {
    1482                 :            :     PyObject *result;
    1483                 :            : 
    1484                 :       5898 :     result = set_copy(so, NULL);
    1485         [ -  + ]:       5898 :     if (result == NULL)
    1486                 :          0 :         return NULL;
    1487         [ +  + ]:       5898 :     if (set_difference_update_internal((PySetObject *) result, other) == 0)
    1488                 :       5858 :         return result;
    1489                 :         40 :     Py_DECREF(result);
    1490                 :         40 :     return NULL;
    1491                 :            : }
    1492                 :            : 
    1493                 :            : static PyObject *
    1494                 :      58680 : set_difference(PySetObject *so, PyObject *other)
    1495                 :            : {
    1496                 :            :     PyObject *result;
    1497                 :            :     PyObject *key;
    1498                 :            :     Py_hash_t hash;
    1499                 :            :     setentry *entry;
    1500                 :      58680 :     Py_ssize_t pos = 0, other_size;
    1501                 :            :     int rv;
    1502                 :            : 
    1503   [ +  +  +  +  :      58680 :     if (PyAnySet_Check(other)) {
             +  +  +  + ]
    1504                 :      58285 :         other_size = PySet_GET_SIZE(other);
    1505                 :            :     }
    1506         [ +  + ]:        395 :     else if (PyDict_CheckExact(other)) {
    1507                 :        125 :         other_size = PyDict_GET_SIZE(other);
    1508                 :            :     }
    1509                 :            :     else {
    1510                 :        270 :         return set_copy_and_difference(so, other);
    1511                 :            :     }
    1512                 :            : 
    1513                 :            :     /* If len(so) much more than len(other), it's more efficient to simply copy
    1514                 :            :      * so and then iterate other looking for common elements. */
    1515         [ +  + ]:      58410 :     if ((PySet_GET_SIZE(so) >> 2) > other_size) {
    1516                 :       5628 :         return set_copy_and_difference(so, other);
    1517                 :            :     }
    1518                 :            : 
    1519                 :      52782 :     result = make_new_set_basetype(Py_TYPE(so), NULL);
    1520         [ -  + ]:      52782 :     if (result == NULL)
    1521                 :          0 :         return NULL;
    1522                 :            : 
    1523         [ +  + ]:      52782 :     if (PyDict_CheckExact(other)) {
    1524         [ +  + ]:       1028 :         while (set_next(so, &pos, &entry)) {
    1525                 :        913 :             key = entry->key;
    1526                 :        913 :             hash = entry->hash;
    1527                 :        913 :             Py_INCREF(key);
    1528                 :        913 :             rv = _PyDict_Contains_KnownHash(other, key, hash);
    1529         [ -  + ]:        913 :             if (rv < 0) {
    1530                 :          0 :                 Py_DECREF(result);
    1531                 :          0 :                 Py_DECREF(key);
    1532                 :          0 :                 return NULL;
    1533                 :            :             }
    1534         [ +  + ]:        913 :             if (!rv) {
    1535         [ -  + ]:        431 :                 if (set_add_entry((PySetObject *)result, key, hash)) {
    1536                 :          0 :                     Py_DECREF(result);
    1537                 :          0 :                     Py_DECREF(key);
    1538                 :          0 :                     return NULL;
    1539                 :            :                 }
    1540                 :            :             }
    1541                 :        913 :             Py_DECREF(key);
    1542                 :            :         }
    1543                 :        115 :         return result;
    1544                 :            :     }
    1545                 :            : 
    1546                 :            :     /* Iterate over so, checking for common elements in other. */
    1547         [ +  + ]:    1102096 :     while (set_next(so, &pos, &entry)) {
    1548                 :    1049429 :         key = entry->key;
    1549                 :    1049429 :         hash = entry->hash;
    1550                 :    1049429 :         Py_INCREF(key);
    1551                 :    1049429 :         rv = set_contains_entry((PySetObject *)other, key, hash);
    1552         [ -  + ]:    1049429 :         if (rv < 0) {
    1553                 :          0 :             Py_DECREF(result);
    1554                 :          0 :             Py_DECREF(key);
    1555                 :          0 :             return NULL;
    1556                 :            :         }
    1557         [ +  + ]:    1049429 :         if (!rv) {
    1558         [ -  + ]:      14024 :             if (set_add_entry((PySetObject *)result, key, hash)) {
    1559                 :          0 :                 Py_DECREF(result);
    1560                 :          0 :                 Py_DECREF(key);
    1561                 :          0 :                 return NULL;
    1562                 :            :             }
    1563                 :            :         }
    1564                 :    1049429 :         Py_DECREF(key);
    1565                 :            :     }
    1566                 :      52667 :     return result;
    1567                 :            : }
    1568                 :            : 
    1569                 :            : static PyObject *
    1570                 :      39221 : set_difference_multi(PySetObject *so, PyObject *args)
    1571                 :            : {
    1572                 :            :     Py_ssize_t i;
    1573                 :            :     PyObject *result, *other;
    1574                 :            : 
    1575         [ +  + ]:      39221 :     if (PyTuple_GET_SIZE(args) == 0)
    1576                 :         24 :         return set_copy(so, NULL);
    1577                 :            : 
    1578                 :      39197 :     other = PyTuple_GET_ITEM(args, 0);
    1579                 :      39197 :     result = set_difference(so, other);
    1580         [ +  + ]:      39197 :     if (result == NULL)
    1581                 :         40 :         return NULL;
    1582                 :            : 
    1583         [ +  + ]:      39181 :     for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
    1584                 :         24 :         other = PyTuple_GET_ITEM(args, i);
    1585         [ -  + ]:         24 :         if (set_difference_update_internal((PySetObject *)result, other)) {
    1586                 :          0 :             Py_DECREF(result);
    1587                 :          0 :             return NULL;
    1588                 :            :         }
    1589                 :            :     }
    1590                 :      39157 :     return result;
    1591                 :            : }
    1592                 :            : 
    1593                 :            : PyDoc_STRVAR(difference_doc,
    1594                 :            : "Return the difference of two or more sets as a new set.\n\
    1595                 :            : \n\
    1596                 :            : (i.e. all elements that are in this set but not the others.)");
    1597                 :            : static PyObject *
    1598                 :      19510 : set_sub(PySetObject *so, PyObject *other)
    1599                 :            : {
    1600   [ +  +  +  +  :      19510 :     if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
          +  +  +  +  +  
          +  +  +  +  +  
                   +  + ]
    1601                 :         27 :         Py_RETURN_NOTIMPLEMENTED;
    1602                 :      19483 :     return set_difference(so, other);
    1603                 :            : }
    1604                 :            : 
    1605                 :            : static PyObject *
    1606                 :        466 : set_isub(PySetObject *so, PyObject *other)
    1607                 :            : {
    1608   [ +  +  +  -  :        466 :     if (!PyAnySet_Check(other))
             +  +  +  - ]
    1609                 :          6 :         Py_RETURN_NOTIMPLEMENTED;
    1610         [ -  + ]:        460 :     if (set_difference_update_internal(so, other))
    1611                 :          0 :         return NULL;
    1612                 :        460 :     Py_INCREF(so);
    1613                 :        460 :     return (PyObject *)so;
    1614                 :            : }
    1615                 :            : 
    1616                 :            : static PyObject *
    1617                 :       2708 : set_symmetric_difference_update(PySetObject *so, PyObject *other)
    1618                 :            : {
    1619                 :            :     PySetObject *otherset;
    1620                 :            :     PyObject *key;
    1621                 :       2708 :     Py_ssize_t pos = 0;
    1622                 :            :     Py_hash_t hash;
    1623                 :            :     setentry *entry;
    1624                 :            :     int rv;
    1625                 :            : 
    1626         [ +  + ]:       2708 :     if ((PyObject *)so == other)
    1627                 :          2 :         return set_clear(so, NULL);
    1628                 :            : 
    1629         [ +  + ]:       2706 :     if (PyDict_CheckExact(other)) {
    1630                 :            :         PyObject *value;
    1631         [ +  + ]:       1256 :         while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
    1632                 :       1144 :             Py_INCREF(key);
    1633                 :       1144 :             rv = set_discard_entry(so, key, hash);
    1634         [ -  + ]:       1144 :             if (rv < 0) {
    1635                 :          0 :                 Py_DECREF(key);
    1636                 :          0 :                 return NULL;
    1637                 :            :             }
    1638         [ +  + ]:       1144 :             if (rv == DISCARD_NOTFOUND) {
    1639         [ -  + ]:        515 :                 if (set_add_entry(so, key, hash)) {
    1640                 :          0 :                     Py_DECREF(key);
    1641                 :          0 :                     return NULL;
    1642                 :            :                 }
    1643                 :            :             }
    1644                 :       1144 :             Py_DECREF(key);
    1645                 :            :         }
    1646                 :        112 :         Py_RETURN_NONE;
    1647                 :            :     }
    1648                 :            : 
    1649   [ +  +  +  +  :       2594 :     if (PyAnySet_Check(other)) {
             +  +  +  + ]
    1650                 :       2348 :         Py_INCREF(other);
    1651                 :       2348 :         otherset = (PySetObject *)other;
    1652                 :            :     } else {
    1653                 :        246 :         otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
    1654         [ +  + ]:        246 :         if (otherset == NULL)
    1655                 :         31 :             return NULL;
    1656                 :            :     }
    1657                 :            : 
    1658         [ +  + ]:      33090 :     while (set_next(otherset, &pos, &entry)) {
    1659                 :      30527 :         key = entry->key;
    1660                 :      30527 :         hash = entry->hash;
    1661                 :      30527 :         Py_INCREF(key);
    1662                 :      30527 :         rv = set_discard_entry(so, key, hash);
    1663         [ -  + ]:      30527 :         if (rv < 0) {
    1664                 :          0 :             Py_DECREF(otherset);
    1665                 :          0 :             Py_DECREF(key);
    1666                 :          0 :             return NULL;
    1667                 :            :         }
    1668         [ +  + ]:      30527 :         if (rv == DISCARD_NOTFOUND) {
    1669         [ -  + ]:      18073 :             if (set_add_entry(so, key, hash)) {
    1670                 :          0 :                 Py_DECREF(otherset);
    1671                 :          0 :                 Py_DECREF(key);
    1672                 :          0 :                 return NULL;
    1673                 :            :             }
    1674                 :            :         }
    1675                 :      30527 :         Py_DECREF(key);
    1676                 :            :     }
    1677                 :       2563 :     Py_DECREF(otherset);
    1678                 :       2563 :     Py_RETURN_NONE;
    1679                 :            : }
    1680                 :            : 
    1681                 :            : PyDoc_STRVAR(symmetric_difference_update_doc,
    1682                 :            : "Update a set with the symmetric difference of itself and another.");
    1683                 :            : 
    1684                 :            : static PyObject *
    1685                 :       1550 : set_symmetric_difference(PySetObject *so, PyObject *other)
    1686                 :            : {
    1687                 :            :     PyObject *rv;
    1688                 :            :     PySetObject *otherset;
    1689                 :            : 
    1690                 :       1550 :     otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
    1691         [ +  + ]:       1550 :     if (otherset == NULL)
    1692                 :         28 :         return NULL;
    1693                 :       1522 :     rv = set_symmetric_difference_update(otherset, (PyObject *)so);
    1694         [ -  + ]:       1522 :     if (rv == NULL) {
    1695                 :          0 :         Py_DECREF(otherset);
    1696                 :          0 :         return NULL;
    1697                 :            :     }
    1698                 :       1522 :     Py_DECREF(rv);
    1699                 :       1522 :     return (PyObject *)otherset;
    1700                 :            : }
    1701                 :            : 
    1702                 :            : PyDoc_STRVAR(symmetric_difference_doc,
    1703                 :            : "Return the symmetric difference of two sets as a new set.\n\
    1704                 :            : \n\
    1705                 :            : (i.e. all elements that are in exactly one of the sets.)");
    1706                 :            : 
    1707                 :            : static PyObject *
    1708                 :        776 : set_xor(PySetObject *so, PyObject *other)
    1709                 :            : {
    1710   [ +  +  +  +  :        776 :     if (!PyAnySet_Check(so) || !PyAnySet_Check(other))
          +  +  +  +  +  
          +  +  +  +  +  
                   +  - ]
    1711                 :         23 :         Py_RETURN_NOTIMPLEMENTED;
    1712                 :        753 :     return set_symmetric_difference(so, other);
    1713                 :            : }
    1714                 :            : 
    1715                 :            : static PyObject *
    1716                 :        414 : set_ixor(PySetObject *so, PyObject *other)
    1717                 :            : {
    1718                 :            :     PyObject *result;
    1719                 :            : 
    1720   [ +  +  +  -  :        414 :     if (!PyAnySet_Check(other))
             +  +  +  - ]
    1721                 :          6 :         Py_RETURN_NOTIMPLEMENTED;
    1722                 :        408 :     result = set_symmetric_difference_update(so, other);
    1723         [ -  + ]:        408 :     if (result == NULL)
    1724                 :          0 :         return NULL;
    1725                 :        408 :     Py_DECREF(result);
    1726                 :        408 :     Py_INCREF(so);
    1727                 :        408 :     return (PyObject *)so;
    1728                 :            : }
    1729                 :            : 
    1730                 :            : static PyObject *
    1731                 :      51198 : set_issubset(PySetObject *so, PyObject *other)
    1732                 :            : {
    1733                 :            :     setentry *entry;
    1734                 :      51198 :     Py_ssize_t pos = 0;
    1735                 :            :     int rv;
    1736                 :            : 
    1737   [ +  +  +  +  :      51198 :     if (!PyAnySet_Check(other)) {
             +  +  +  + ]
    1738                 :        213 :         PyObject *tmp = set_intersection(so, other);
    1739         [ +  + ]:        213 :         if (tmp == NULL) {
    1740                 :         44 :             return NULL;
    1741                 :            :         }
    1742                 :        169 :         int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so));
    1743                 :        169 :         Py_DECREF(tmp);
    1744                 :        169 :         return PyBool_FromLong(result);
    1745                 :            :     }
    1746         [ +  + ]:      50985 :     if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
    1747                 :       3599 :         Py_RETURN_FALSE;
    1748                 :            : 
    1749         [ +  + ]:     137450 :     while (set_next(so, &pos, &entry)) {
    1750                 :      95021 :         PyObject *key = entry->key;
    1751                 :      95021 :         Py_INCREF(key);
    1752                 :      95021 :         rv = set_contains_entry((PySetObject *)other, key, entry->hash);
    1753                 :      95021 :         Py_DECREF(key);
    1754         [ -  + ]:      95021 :         if (rv < 0) {
    1755                 :          0 :             return NULL;
    1756                 :            :         }
    1757         [ +  + ]:      95021 :         if (!rv) {
    1758                 :       4957 :             Py_RETURN_FALSE;
    1759                 :            :         }
    1760                 :            :     }
    1761                 :      42429 :     Py_RETURN_TRUE;
    1762                 :            : }
    1763                 :            : 
    1764                 :            : PyDoc_STRVAR(issubset_doc, "Report whether another set contains this set.");
    1765                 :            : 
    1766                 :            : static PyObject *
    1767                 :      14126 : set_issuperset(PySetObject *so, PyObject *other)
    1768                 :            : {
    1769   [ +  +  +  +  :      14126 :     if (PyAnySet_Check(other)) {
             +  +  +  + ]
    1770                 :       6580 :         return set_issubset((PySetObject *)other, (PyObject *)so);
    1771                 :            :     }
    1772                 :            : 
    1773                 :       7546 :     PyObject *key, *it = PyObject_GetIter(other);
    1774         [ -  + ]:       7546 :     if (it == NULL) {
    1775                 :          0 :         return NULL;
    1776                 :            :     }
    1777         [ +  + ]:      27932 :     while ((key = PyIter_Next(it)) != NULL) {
    1778                 :      20510 :         int rv = set_contains_key(so, key);
    1779                 :      20510 :         Py_DECREF(key);
    1780         [ -  + ]:      20510 :         if (rv < 0) {
    1781                 :          0 :             Py_DECREF(it);
    1782                 :          0 :             return NULL;
    1783                 :            :         }
    1784         [ +  + ]:      20510 :         if (!rv) {
    1785                 :        124 :             Py_DECREF(it);
    1786                 :        124 :             Py_RETURN_FALSE;
    1787                 :            :         }
    1788                 :            :     }
    1789                 :       7422 :     Py_DECREF(it);
    1790         [ +  + ]:       7422 :     if (PyErr_Occurred()) {
    1791                 :         43 :         return NULL;
    1792                 :            :     }
    1793                 :       7379 :     Py_RETURN_TRUE;
    1794                 :            : }
    1795                 :            : 
    1796                 :            : PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set.");
    1797                 :            : 
    1798                 :            : static PyObject *
    1799                 :      69806 : set_richcompare(PySetObject *v, PyObject *w, int op)
    1800                 :            : {
    1801                 :            :     PyObject *r1;
    1802                 :            :     int r2;
    1803                 :            : 
    1804   [ +  +  +  +  :      69806 :     if(!PyAnySet_Check(w))
             +  +  +  + ]
    1805                 :        136 :         Py_RETURN_NOTIMPLEMENTED;
    1806                 :            : 
    1807   [ +  +  +  +  :      69670 :     switch (op) {
                +  +  - ]
    1808                 :      25810 :     case Py_EQ:
    1809         [ +  + ]:      25810 :         if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
    1810                 :       6803 :             Py_RETURN_FALSE;
    1811         [ +  + ]:      19007 :         if (v->hash != -1  &&
    1812         [ +  + ]:      10234 :             ((PySetObject *)w)->hash != -1 &&
    1813         [ +  + ]:      10206 :             v->hash != ((PySetObject *)w)->hash)
    1814                 :       1944 :             Py_RETURN_FALSE;
    1815                 :      17063 :         return set_issubset(v, w);
    1816                 :       4856 :     case Py_NE:
    1817                 :       4856 :         r1 = set_richcompare(v, w, Py_EQ);
    1818         [ -  + ]:       4856 :         if (r1 == NULL)
    1819                 :          0 :             return NULL;
    1820                 :       4856 :         r2 = PyObject_IsTrue(r1);
    1821                 :       4856 :         Py_DECREF(r1);
    1822         [ -  + ]:       4856 :         if (r2 < 0)
    1823                 :          0 :             return NULL;
    1824                 :       4856 :         return PyBool_FromLong(!r2);
    1825                 :      25296 :     case Py_LE:
    1826                 :      25296 :         return set_issubset(v, w);
    1827                 :       4544 :     case Py_GE:
    1828                 :       4544 :         return set_issuperset(v, w);
    1829                 :       4640 :     case Py_LT:
    1830         [ +  + ]:       4640 :         if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
    1831                 :       3005 :             Py_RETURN_FALSE;
    1832                 :       1635 :         return set_issubset(v, w);
    1833                 :       4524 :     case Py_GT:
    1834         [ +  + ]:       4524 :         if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
    1835                 :       2899 :             Py_RETURN_FALSE;
    1836                 :       1625 :         return set_issuperset(v, w);
    1837                 :            :     }
    1838                 :          0 :     Py_RETURN_NOTIMPLEMENTED;
    1839                 :            : }
    1840                 :            : 
    1841                 :            : static PyObject *
    1842                 :    1387830 : set_add(PySetObject *so, PyObject *key)
    1843                 :            : {
    1844         [ +  + ]:    1387830 :     if (set_add_key(so, key))
    1845                 :          4 :         return NULL;
    1846                 :    1387826 :     Py_RETURN_NONE;
    1847                 :            : }
    1848                 :            : 
    1849                 :            : PyDoc_STRVAR(add_doc,
    1850                 :            : "Add an element to a set.\n\
    1851                 :            : \n\
    1852                 :            : This has no effect if the element is already present.");
    1853                 :            : 
    1854                 :            : static int
    1855                 :   33625705 : set_contains(PySetObject *so, PyObject *key)
    1856                 :            : {
    1857                 :            :     PyObject *tmpkey;
    1858                 :            :     int rv;
    1859                 :            : 
    1860                 :   33625705 :     rv = set_contains_key(so, key);
    1861         [ +  + ]:   33625705 :     if (rv < 0) {
    1862   [ +  +  +  +  :         18 :         if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
                   -  + ]
    1863                 :          8 :             return -1;
    1864                 :         10 :         PyErr_Clear();
    1865                 :         10 :         tmpkey = make_new_set(&PyFrozenSet_Type, key);
    1866         [ -  + ]:         10 :         if (tmpkey == NULL)
    1867                 :          0 :             return -1;
    1868                 :         10 :         rv = set_contains_key(so, tmpkey);
    1869                 :         10 :         Py_DECREF(tmpkey);
    1870                 :            :     }
    1871                 :   33625697 :     return rv;
    1872                 :            : }
    1873                 :            : 
    1874                 :            : static PyObject *
    1875                 :     516948 : set_direct_contains(PySetObject *so, PyObject *key)
    1876                 :            : {
    1877                 :            :     long result;
    1878                 :            : 
    1879                 :     516948 :     result = set_contains(so, key);
    1880         [ +  + ]:     516948 :     if (result < 0)
    1881                 :          8 :         return NULL;
    1882                 :     516940 :     return PyBool_FromLong(result);
    1883                 :            : }
    1884                 :            : 
    1885                 :            : PyDoc_STRVAR(contains_doc, "x.__contains__(y) <==> y in x.");
    1886                 :            : 
    1887                 :            : static PyObject *
    1888                 :      61328 : set_remove(PySetObject *so, PyObject *key)
    1889                 :            : {
    1890                 :            :     PyObject *tmpkey;
    1891                 :            :     int rv;
    1892                 :            : 
    1893                 :      61328 :     rv = set_discard_key(so, key);
    1894         [ +  + ]:      61328 :     if (rv < 0) {
    1895   [ +  +  +  +  :         10 :         if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
                   -  + ]
    1896                 :          4 :             return NULL;
    1897                 :          6 :         PyErr_Clear();
    1898                 :          6 :         tmpkey = make_new_set(&PyFrozenSet_Type, key);
    1899         [ -  + ]:          6 :         if (tmpkey == NULL)
    1900                 :          0 :             return NULL;
    1901                 :          6 :         rv = set_discard_key(so, tmpkey);
    1902                 :          6 :         Py_DECREF(tmpkey);
    1903         [ -  + ]:          6 :         if (rv < 0)
    1904                 :          0 :             return NULL;
    1905                 :            :     }
    1906                 :            : 
    1907         [ +  + ]:      61324 :     if (rv == DISCARD_NOTFOUND) {
    1908                 :         17 :         _PyErr_SetKeyError(key);
    1909                 :         17 :         return NULL;
    1910                 :            :     }
    1911                 :      61307 :     Py_RETURN_NONE;
    1912                 :            : }
    1913                 :            : 
    1914                 :            : PyDoc_STRVAR(remove_doc,
    1915                 :            : "Remove an element from a set; it must be a member.\n\
    1916                 :            : \n\
    1917                 :            : If the element is not a member, raise a KeyError.");
    1918                 :            : 
    1919                 :            : static PyObject *
    1920                 :      29973 : set_discard(PySetObject *so, PyObject *key)
    1921                 :            : {
    1922                 :            :     PyObject *tmpkey;
    1923                 :            :     int rv;
    1924                 :            : 
    1925                 :      29973 :     rv = set_discard_key(so, key);
    1926         [ +  + ]:      29973 :     if (rv < 0) {
    1927   [ +  +  +  +  :          8 :         if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
                   -  + ]
    1928                 :          4 :             return NULL;
    1929                 :          4 :         PyErr_Clear();
    1930                 :          4 :         tmpkey = make_new_set(&PyFrozenSet_Type, key);
    1931         [ -  + ]:          4 :         if (tmpkey == NULL)
    1932                 :          0 :             return NULL;
    1933                 :          4 :         rv = set_discard_key(so, tmpkey);
    1934                 :          4 :         Py_DECREF(tmpkey);
    1935         [ -  + ]:          4 :         if (rv < 0)
    1936                 :          0 :             return NULL;
    1937                 :            :     }
    1938                 :      29969 :     Py_RETURN_NONE;
    1939                 :            : }
    1940                 :            : 
    1941                 :            : PyDoc_STRVAR(discard_doc,
    1942                 :            : "Remove an element from a set if it is a member.\n\
    1943                 :            : \n\
    1944                 :            : Unlike set.remove(), the discard() method does not raise\n\
    1945                 :            : an exception when an element is missing from the set.");
    1946                 :            : 
    1947                 :            : static PyObject *
    1948                 :        433 : set_reduce(PySetObject *so, PyObject *Py_UNUSED(ignored))
    1949                 :            : {
    1950                 :        433 :     PyObject *keys=NULL, *args=NULL, *result=NULL, *state=NULL;
    1951                 :            : 
    1952                 :        433 :     keys = PySequence_List((PyObject *)so);
    1953         [ -  + ]:        433 :     if (keys == NULL)
    1954                 :          0 :         goto done;
    1955                 :        433 :     args = PyTuple_Pack(1, keys);
    1956         [ -  + ]:        433 :     if (args == NULL)
    1957                 :          0 :         goto done;
    1958                 :        433 :     state = _PyObject_GetState((PyObject *)so);
    1959         [ -  + ]:        433 :     if (state == NULL)
    1960                 :          0 :         goto done;
    1961                 :        433 :     result = PyTuple_Pack(3, Py_TYPE(so), args, state);
    1962                 :        433 : done:
    1963                 :        433 :     Py_XDECREF(args);
    1964                 :        433 :     Py_XDECREF(keys);
    1965                 :        433 :     Py_XDECREF(state);
    1966                 :        433 :     return result;
    1967                 :            : }
    1968                 :            : 
    1969                 :            : static PyObject *
    1970                 :         10 : set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored))
    1971                 :            : {
    1972                 :            :     Py_ssize_t res;
    1973                 :            : 
    1974                 :         10 :     res = _PyObject_SIZE(Py_TYPE(so));
    1975         [ +  + ]:         10 :     if (so->table != so->smalltable)
    1976                 :          4 :         res = res + (so->mask + 1) * sizeof(setentry);
    1977                 :         10 :     return PyLong_FromSsize_t(res);
    1978                 :            : }
    1979                 :            : 
    1980                 :            : PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes");
    1981                 :            : static int
    1982                 :      12067 : set_init(PySetObject *self, PyObject *args, PyObject *kwds)
    1983                 :            : {
    1984                 :      12067 :     PyObject *iterable = NULL;
    1985                 :            : 
    1986   [ +  +  +  + ]:      12067 :      if (!_PyArg_NoKeywords("set", kwds))
    1987                 :          6 :         return -1;
    1988         [ +  + ]:      12061 :     if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
    1989                 :          3 :         return -1;
    1990         [ +  + ]:      12058 :     if (self->fill)
    1991                 :          4 :         set_clear_internal(self);
    1992                 :      12058 :     self->hash = -1;
    1993         [ +  + ]:      12058 :     if (iterable == NULL)
    1994                 :         22 :         return 0;
    1995                 :      12036 :     return set_update_internal(self, iterable);
    1996                 :            : }
    1997                 :            : 
    1998                 :            : static PyObject*
    1999                 :     997431 : set_vectorcall(PyObject *type, PyObject * const*args,
    2000                 :            :                size_t nargsf, PyObject *kwnames)
    2001                 :            : {
    2002                 :            :     assert(PyType_Check(type));
    2003                 :            : 
    2004   [ -  +  -  - ]:     997431 :     if (!_PyArg_NoKwnames("set", kwnames)) {
    2005                 :          0 :         return NULL;
    2006                 :            :     }
    2007                 :            : 
    2008                 :     997431 :     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    2009   [ +  -  +  +  :     997431 :     if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
                   +  - ]
    2010                 :          1 :         return NULL;
    2011                 :            :     }
    2012                 :            : 
    2013         [ +  + ]:     997430 :     if (nargs) {
    2014                 :     685906 :         return make_new_set(_PyType_CAST(type), args[0]);
    2015                 :            :     }
    2016                 :            : 
    2017                 :     311524 :     return make_new_set(_PyType_CAST(type), NULL);
    2018                 :            : }
    2019                 :            : 
    2020                 :            : static PySequenceMethods set_as_sequence = {
    2021                 :            :     set_len,                            /* sq_length */
    2022                 :            :     0,                                  /* sq_concat */
    2023                 :            :     0,                                  /* sq_repeat */
    2024                 :            :     0,                                  /* sq_item */
    2025                 :            :     0,                                  /* sq_slice */
    2026                 :            :     0,                                  /* sq_ass_item */
    2027                 :            :     0,                                  /* sq_ass_slice */
    2028                 :            :     (objobjproc)set_contains,           /* sq_contains */
    2029                 :            : };
    2030                 :            : 
    2031                 :            : /* set object ********************************************************/
    2032                 :            : 
    2033                 :            : #ifdef Py_DEBUG
    2034                 :            : static PyObject *test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored));
    2035                 :            : 
    2036                 :            : PyDoc_STRVAR(test_c_api_doc, "Exercises C API.  Returns True.\n\
    2037                 :            : All is well if assertions don't fail.");
    2038                 :            : #endif
    2039                 :            : 
    2040                 :            : static PyMethodDef set_methods[] = {
    2041                 :            :     {"add",             (PyCFunction)set_add,           METH_O,
    2042                 :            :      add_doc},
    2043                 :            :     {"clear",           (PyCFunction)set_clear,         METH_NOARGS,
    2044                 :            :      clear_doc},
    2045                 :            :     {"__contains__",(PyCFunction)set_direct_contains,           METH_O | METH_COEXIST,
    2046                 :            :      contains_doc},
    2047                 :            :     {"copy",            (PyCFunction)set_copy,          METH_NOARGS,
    2048                 :            :      copy_doc},
    2049                 :            :     {"discard",         (PyCFunction)set_discard,       METH_O,
    2050                 :            :      discard_doc},
    2051                 :            :     {"difference",      (PyCFunction)set_difference_multi,      METH_VARARGS,
    2052                 :            :      difference_doc},
    2053                 :            :     {"difference_update",       (PyCFunction)set_difference_update,     METH_VARARGS,
    2054                 :            :      difference_update_doc},
    2055                 :            :     {"intersection",(PyCFunction)set_intersection_multi,        METH_VARARGS,
    2056                 :            :      intersection_doc},
    2057                 :            :     {"intersection_update",(PyCFunction)set_intersection_update_multi,          METH_VARARGS,
    2058                 :            :      intersection_update_doc},
    2059                 :            :     {"isdisjoint",      (PyCFunction)set_isdisjoint,    METH_O,
    2060                 :            :      isdisjoint_doc},
    2061                 :            :     {"issubset",        (PyCFunction)set_issubset,      METH_O,
    2062                 :            :      issubset_doc},
    2063                 :            :     {"issuperset",      (PyCFunction)set_issuperset,    METH_O,
    2064                 :            :      issuperset_doc},
    2065                 :            :     {"pop",             (PyCFunction)set_pop,           METH_NOARGS,
    2066                 :            :      pop_doc},
    2067                 :            :     {"__reduce__",      (PyCFunction)set_reduce,        METH_NOARGS,
    2068                 :            :      reduce_doc},
    2069                 :            :     {"remove",          (PyCFunction)set_remove,        METH_O,
    2070                 :            :      remove_doc},
    2071                 :            :     {"__sizeof__",      (PyCFunction)set_sizeof,        METH_NOARGS,
    2072                 :            :      sizeof_doc},
    2073                 :            :     {"symmetric_difference",(PyCFunction)set_symmetric_difference,      METH_O,
    2074                 :            :      symmetric_difference_doc},
    2075                 :            :     {"symmetric_difference_update",(PyCFunction)set_symmetric_difference_update,        METH_O,
    2076                 :            :      symmetric_difference_update_doc},
    2077                 :            : #ifdef Py_DEBUG
    2078                 :            :     {"test_c_api",      (PyCFunction)test_c_api,        METH_NOARGS,
    2079                 :            :      test_c_api_doc},
    2080                 :            : #endif
    2081                 :            :     {"union",           (PyCFunction)set_union,         METH_VARARGS,
    2082                 :            :      union_doc},
    2083                 :            :     {"update",          (PyCFunction)set_update,        METH_VARARGS,
    2084                 :            :      update_doc},
    2085                 :            :     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    2086                 :            :     {NULL,              NULL}   /* sentinel */
    2087                 :            : };
    2088                 :            : 
    2089                 :            : static PyNumberMethods set_as_number = {
    2090                 :            :     0,                                  /*nb_add*/
    2091                 :            :     (binaryfunc)set_sub,                /*nb_subtract*/
    2092                 :            :     0,                                  /*nb_multiply*/
    2093                 :            :     0,                                  /*nb_remainder*/
    2094                 :            :     0,                                  /*nb_divmod*/
    2095                 :            :     0,                                  /*nb_power*/
    2096                 :            :     0,                                  /*nb_negative*/
    2097                 :            :     0,                                  /*nb_positive*/
    2098                 :            :     0,                                  /*nb_absolute*/
    2099                 :            :     0,                                  /*nb_bool*/
    2100                 :            :     0,                                  /*nb_invert*/
    2101                 :            :     0,                                  /*nb_lshift*/
    2102                 :            :     0,                                  /*nb_rshift*/
    2103                 :            :     (binaryfunc)set_and,                /*nb_and*/
    2104                 :            :     (binaryfunc)set_xor,                /*nb_xor*/
    2105                 :            :     (binaryfunc)set_or,                 /*nb_or*/
    2106                 :            :     0,                                  /*nb_int*/
    2107                 :            :     0,                                  /*nb_reserved*/
    2108                 :            :     0,                                  /*nb_float*/
    2109                 :            :     0,                                  /*nb_inplace_add*/
    2110                 :            :     (binaryfunc)set_isub,               /*nb_inplace_subtract*/
    2111                 :            :     0,                                  /*nb_inplace_multiply*/
    2112                 :            :     0,                                  /*nb_inplace_remainder*/
    2113                 :            :     0,                                  /*nb_inplace_power*/
    2114                 :            :     0,                                  /*nb_inplace_lshift*/
    2115                 :            :     0,                                  /*nb_inplace_rshift*/
    2116                 :            :     (binaryfunc)set_iand,               /*nb_inplace_and*/
    2117                 :            :     (binaryfunc)set_ixor,               /*nb_inplace_xor*/
    2118                 :            :     (binaryfunc)set_ior,                /*nb_inplace_or*/
    2119                 :            : };
    2120                 :            : 
    2121                 :            : PyDoc_STRVAR(set_doc,
    2122                 :            : "set() -> new empty set object\n\
    2123                 :            : set(iterable) -> new set object\n\
    2124                 :            : \n\
    2125                 :            : Build an unordered collection of unique elements.");
    2126                 :            : 
    2127                 :            : PyTypeObject PySet_Type = {
    2128                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    2129                 :            :     "set",                              /* tp_name */
    2130                 :            :     sizeof(PySetObject),                /* tp_basicsize */
    2131                 :            :     0,                                  /* tp_itemsize */
    2132                 :            :     /* methods */
    2133                 :            :     (destructor)set_dealloc,            /* tp_dealloc */
    2134                 :            :     0,                                  /* tp_vectorcall_offset */
    2135                 :            :     0,                                  /* tp_getattr */
    2136                 :            :     0,                                  /* tp_setattr */
    2137                 :            :     0,                                  /* tp_as_async */
    2138                 :            :     (reprfunc)set_repr,                 /* tp_repr */
    2139                 :            :     &set_as_number,                     /* tp_as_number */
    2140                 :            :     &set_as_sequence,                   /* tp_as_sequence */
    2141                 :            :     0,                                  /* tp_as_mapping */
    2142                 :            :     PyObject_HashNotImplemented,        /* tp_hash */
    2143                 :            :     0,                                  /* tp_call */
    2144                 :            :     0,                                  /* tp_str */
    2145                 :            :     PyObject_GenericGetAttr,            /* tp_getattro */
    2146                 :            :     0,                                  /* tp_setattro */
    2147                 :            :     0,                                  /* tp_as_buffer */
    2148                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
    2149                 :            :         Py_TPFLAGS_BASETYPE |
    2150                 :            :         _Py_TPFLAGS_MATCH_SELF,       /* tp_flags */
    2151                 :            :     set_doc,                            /* tp_doc */
    2152                 :            :     (traverseproc)set_traverse,         /* tp_traverse */
    2153                 :            :     (inquiry)set_clear_internal,        /* tp_clear */
    2154                 :            :     (richcmpfunc)set_richcompare,       /* tp_richcompare */
    2155                 :            :     offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    2156                 :            :     (getiterfunc)set_iter,              /* tp_iter */
    2157                 :            :     0,                                  /* tp_iternext */
    2158                 :            :     set_methods,                        /* tp_methods */
    2159                 :            :     0,                                  /* tp_members */
    2160                 :            :     0,                                  /* tp_getset */
    2161                 :            :     0,                                  /* tp_base */
    2162                 :            :     0,                                  /* tp_dict */
    2163                 :            :     0,                                  /* tp_descr_get */
    2164                 :            :     0,                                  /* tp_descr_set */
    2165                 :            :     0,                                  /* tp_dictoffset */
    2166                 :            :     (initproc)set_init,                 /* tp_init */
    2167                 :            :     PyType_GenericAlloc,                /* tp_alloc */
    2168                 :            :     set_new,                            /* tp_new */
    2169                 :            :     PyObject_GC_Del,                    /* tp_free */
    2170                 :            :     .tp_vectorcall = set_vectorcall,
    2171                 :            : };
    2172                 :            : 
    2173                 :            : /* frozenset object ********************************************************/
    2174                 :            : 
    2175                 :            : 
    2176                 :            : static PyMethodDef frozenset_methods[] = {
    2177                 :            :     {"__contains__",(PyCFunction)set_direct_contains,           METH_O | METH_COEXIST,
    2178                 :            :      contains_doc},
    2179                 :            :     {"copy",            (PyCFunction)frozenset_copy,    METH_NOARGS,
    2180                 :            :      copy_doc},
    2181                 :            :     {"difference",      (PyCFunction)set_difference_multi,      METH_VARARGS,
    2182                 :            :      difference_doc},
    2183                 :            :     {"intersection",    (PyCFunction)set_intersection_multi,    METH_VARARGS,
    2184                 :            :      intersection_doc},
    2185                 :            :     {"isdisjoint",      (PyCFunction)set_isdisjoint,    METH_O,
    2186                 :            :      isdisjoint_doc},
    2187                 :            :     {"issubset",        (PyCFunction)set_issubset,      METH_O,
    2188                 :            :      issubset_doc},
    2189                 :            :     {"issuperset",      (PyCFunction)set_issuperset,    METH_O,
    2190                 :            :      issuperset_doc},
    2191                 :            :     {"__reduce__",      (PyCFunction)set_reduce,        METH_NOARGS,
    2192                 :            :      reduce_doc},
    2193                 :            :     {"__sizeof__",      (PyCFunction)set_sizeof,        METH_NOARGS,
    2194                 :            :      sizeof_doc},
    2195                 :            :     {"symmetric_difference",(PyCFunction)set_symmetric_difference,      METH_O,
    2196                 :            :      symmetric_difference_doc},
    2197                 :            :     {"union",           (PyCFunction)set_union,         METH_VARARGS,
    2198                 :            :      union_doc},
    2199                 :            :     {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    2200                 :            :     {NULL,              NULL}   /* sentinel */
    2201                 :            : };
    2202                 :            : 
    2203                 :            : static PyNumberMethods frozenset_as_number = {
    2204                 :            :     0,                                  /*nb_add*/
    2205                 :            :     (binaryfunc)set_sub,                /*nb_subtract*/
    2206                 :            :     0,                                  /*nb_multiply*/
    2207                 :            :     0,                                  /*nb_remainder*/
    2208                 :            :     0,                                  /*nb_divmod*/
    2209                 :            :     0,                                  /*nb_power*/
    2210                 :            :     0,                                  /*nb_negative*/
    2211                 :            :     0,                                  /*nb_positive*/
    2212                 :            :     0,                                  /*nb_absolute*/
    2213                 :            :     0,                                  /*nb_bool*/
    2214                 :            :     0,                                  /*nb_invert*/
    2215                 :            :     0,                                  /*nb_lshift*/
    2216                 :            :     0,                                  /*nb_rshift*/
    2217                 :            :     (binaryfunc)set_and,                /*nb_and*/
    2218                 :            :     (binaryfunc)set_xor,                /*nb_xor*/
    2219                 :            :     (binaryfunc)set_or,                 /*nb_or*/
    2220                 :            : };
    2221                 :            : 
    2222                 :            : PyDoc_STRVAR(frozenset_doc,
    2223                 :            : "frozenset() -> empty frozenset object\n\
    2224                 :            : frozenset(iterable) -> frozenset object\n\
    2225                 :            : \n\
    2226                 :            : Build an immutable unordered collection of unique elements.");
    2227                 :            : 
    2228                 :            : PyTypeObject PyFrozenSet_Type = {
    2229                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    2230                 :            :     "frozenset",                        /* tp_name */
    2231                 :            :     sizeof(PySetObject),                /* tp_basicsize */
    2232                 :            :     0,                                  /* tp_itemsize */
    2233                 :            :     /* methods */
    2234                 :            :     (destructor)set_dealloc,            /* tp_dealloc */
    2235                 :            :     0,                                  /* tp_vectorcall_offset */
    2236                 :            :     0,                                  /* tp_getattr */
    2237                 :            :     0,                                  /* tp_setattr */
    2238                 :            :     0,                                  /* tp_as_async */
    2239                 :            :     (reprfunc)set_repr,                 /* tp_repr */
    2240                 :            :     &frozenset_as_number,               /* tp_as_number */
    2241                 :            :     &set_as_sequence,                   /* tp_as_sequence */
    2242                 :            :     0,                                  /* tp_as_mapping */
    2243                 :            :     frozenset_hash,                     /* tp_hash */
    2244                 :            :     0,                                  /* tp_call */
    2245                 :            :     0,                                  /* tp_str */
    2246                 :            :     PyObject_GenericGetAttr,            /* tp_getattro */
    2247                 :            :     0,                                  /* tp_setattro */
    2248                 :            :     0,                                  /* tp_as_buffer */
    2249                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
    2250                 :            :         Py_TPFLAGS_BASETYPE |
    2251                 :            :         _Py_TPFLAGS_MATCH_SELF,       /* tp_flags */
    2252                 :            :     frozenset_doc,                      /* tp_doc */
    2253                 :            :     (traverseproc)set_traverse,         /* tp_traverse */
    2254                 :            :     (inquiry)set_clear_internal,        /* tp_clear */
    2255                 :            :     (richcmpfunc)set_richcompare,       /* tp_richcompare */
    2256                 :            :     offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    2257                 :            :     (getiterfunc)set_iter,              /* tp_iter */
    2258                 :            :     0,                                  /* tp_iternext */
    2259                 :            :     frozenset_methods,                  /* tp_methods */
    2260                 :            :     0,                                  /* tp_members */
    2261                 :            :     0,                                  /* tp_getset */
    2262                 :            :     0,                                  /* tp_base */
    2263                 :            :     0,                                  /* tp_dict */
    2264                 :            :     0,                                  /* tp_descr_get */
    2265                 :            :     0,                                  /* tp_descr_set */
    2266                 :            :     0,                                  /* tp_dictoffset */
    2267                 :            :     0,                                  /* tp_init */
    2268                 :            :     PyType_GenericAlloc,                /* tp_alloc */
    2269                 :            :     frozenset_new,                      /* tp_new */
    2270                 :            :     PyObject_GC_Del,                    /* tp_free */
    2271                 :            :     .tp_vectorcall = frozenset_vectorcall,
    2272                 :            : };
    2273                 :            : 
    2274                 :            : 
    2275                 :            : /***** C API functions *************************************************/
    2276                 :            : 
    2277                 :            : PyObject *
    2278                 :    3831952 : PySet_New(PyObject *iterable)
    2279                 :            : {
    2280                 :    3831952 :     return make_new_set(&PySet_Type, iterable);
    2281                 :            : }
    2282                 :            : 
    2283                 :            : PyObject *
    2284                 :     211620 : PyFrozenSet_New(PyObject *iterable)
    2285                 :            : {
    2286                 :     211620 :     return make_new_set(&PyFrozenSet_Type, iterable);
    2287                 :            : }
    2288                 :            : 
    2289                 :            : Py_ssize_t
    2290                 :      37974 : PySet_Size(PyObject *anyset)
    2291                 :            : {
    2292   [ -  +  -  -  :      37974 :     if (!PyAnySet_Check(anyset)) {
             -  -  -  - ]
    2293                 :          0 :         PyErr_BadInternalCall();
    2294                 :          0 :         return -1;
    2295                 :            :     }
    2296                 :      37974 :     return PySet_GET_SIZE(anyset);
    2297                 :            : }
    2298                 :            : 
    2299                 :            : int
    2300                 :      37673 : PySet_Clear(PyObject *set)
    2301                 :            : {
    2302   [ -  +  -  - ]:      37673 :     if (!PySet_Check(set)) {
    2303                 :          0 :         PyErr_BadInternalCall();
    2304                 :          0 :         return -1;
    2305                 :            :     }
    2306                 :      37673 :     return set_clear_internal((PySetObject *)set);
    2307                 :            : }
    2308                 :            : 
    2309                 :            : int
    2310                 :    3209971 : PySet_Contains(PyObject *anyset, PyObject *key)
    2311                 :            : {
    2312   [ -  +  -  -  :    3209971 :     if (!PyAnySet_Check(anyset)) {
             -  -  -  - ]
    2313                 :          0 :         PyErr_BadInternalCall();
    2314                 :          0 :         return -1;
    2315                 :            :     }
    2316                 :    3209971 :     return set_contains_key((PySetObject *)anyset, key);
    2317                 :            : }
    2318                 :            : 
    2319                 :            : int
    2320                 :    1620388 : PySet_Discard(PyObject *set, PyObject *key)
    2321                 :            : {
    2322   [ -  +  -  - ]:    1620388 :     if (!PySet_Check(set)) {
    2323                 :          0 :         PyErr_BadInternalCall();
    2324                 :          0 :         return -1;
    2325                 :            :     }
    2326                 :    1620388 :     return set_discard_key((PySetObject *)set, key);
    2327                 :            : }
    2328                 :            : 
    2329                 :            : int
    2330                 :    3853491 : PySet_Add(PyObject *anyset, PyObject *key)
    2331                 :            : {
    2332   [ +  +  +  -  :    4126955 :     if (!PySet_Check(anyset) &&
                   -  + ]
    2333   [ -  -  -  + ]:     546928 :         (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
    2334                 :          0 :         PyErr_BadInternalCall();
    2335                 :          0 :         return -1;
    2336                 :            :     }
    2337                 :    3853491 :     return set_add_key((PySetObject *)anyset, key);
    2338                 :            : }
    2339                 :            : 
    2340                 :            : int
    2341                 :     165531 : _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
    2342                 :            : {
    2343                 :            :     setentry *entry;
    2344                 :            : 
    2345   [ +  +  -  +  :     165531 :     if (!PyAnySet_Check(set)) {
             -  -  -  - ]
    2346                 :          0 :         PyErr_BadInternalCall();
    2347                 :          0 :         return -1;
    2348                 :            :     }
    2349         [ +  + ]:     165531 :     if (set_next((PySetObject *)set, pos, &entry) == 0)
    2350                 :      42939 :         return 0;
    2351                 :     122592 :     *key = entry->key;
    2352                 :     122592 :     *hash = entry->hash;
    2353                 :     122592 :     return 1;
    2354                 :            : }
    2355                 :            : 
    2356                 :            : PyObject *
    2357                 :          0 : PySet_Pop(PyObject *set)
    2358                 :            : {
    2359   [ #  #  #  # ]:          0 :     if (!PySet_Check(set)) {
    2360                 :          0 :         PyErr_BadInternalCall();
    2361                 :          0 :         return NULL;
    2362                 :            :     }
    2363                 :          0 :     return set_pop((PySetObject *)set, NULL);
    2364                 :            : }
    2365                 :            : 
    2366                 :            : int
    2367                 :       6820 : _PySet_Update(PyObject *set, PyObject *iterable)
    2368                 :            : {
    2369   [ -  +  -  - ]:       6820 :     if (!PySet_Check(set)) {
    2370                 :          0 :         PyErr_BadInternalCall();
    2371                 :          0 :         return -1;
    2372                 :            :     }
    2373                 :       6820 :     return set_update_internal((PySetObject *)set, iterable);
    2374                 :            : }
    2375                 :            : 
    2376                 :            : /* Exported for the gdb plugin's benefit. */
    2377                 :            : PyObject *_PySet_Dummy = dummy;
    2378                 :            : 
    2379                 :            : #ifdef Py_DEBUG
    2380                 :            : 
    2381                 :            : /* Test code to be called with any three element set.
    2382                 :            :    Returns True and original set is restored. */
    2383                 :            : 
    2384                 :            : #define assertRaises(call_return_value, exception)              \
    2385                 :            :     do {                                                        \
    2386                 :            :         assert(call_return_value);                              \
    2387                 :            :         assert(PyErr_ExceptionMatches(exception));              \
    2388                 :            :         PyErr_Clear();                                          \
    2389                 :            :     } while(0)
    2390                 :            : 
    2391                 :            : static PyObject *
    2392                 :            : test_c_api(PySetObject *so, PyObject *Py_UNUSED(ignored))
    2393                 :            : {
    2394                 :            :     Py_ssize_t count;
    2395                 :            :     const char *s;
    2396                 :            :     Py_ssize_t i;
    2397                 :            :     PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL;
    2398                 :            :     PyObject *ob = (PyObject *)so;
    2399                 :            :     Py_hash_t hash;
    2400                 :            :     PyObject *str;
    2401                 :            : 
    2402                 :            :     /* Verify preconditions */
    2403                 :            :     assert(PyAnySet_Check(ob));
    2404                 :            :     assert(PyAnySet_CheckExact(ob));
    2405                 :            :     assert(!PyFrozenSet_CheckExact(ob));
    2406                 :            : 
    2407                 :            :     /* so.clear(); so |= set("abc"); */
    2408                 :            :     str = PyUnicode_FromString("abc");
    2409                 :            :     if (str == NULL)
    2410                 :            :         return NULL;
    2411                 :            :     set_clear_internal(so);
    2412                 :            :     if (set_update_internal(so, str)) {
    2413                 :            :         Py_DECREF(str);
    2414                 :            :         return NULL;
    2415                 :            :     }
    2416                 :            :     Py_DECREF(str);
    2417                 :            : 
    2418                 :            :     /* Exercise type/size checks */
    2419                 :            :     assert(PySet_Size(ob) == 3);
    2420                 :            :     assert(PySet_GET_SIZE(ob) == 3);
    2421                 :            : 
    2422                 :            :     /* Raise TypeError for non-iterable constructor arguments */
    2423                 :            :     assertRaises(PySet_New(Py_None) == NULL, PyExc_TypeError);
    2424                 :            :     assertRaises(PyFrozenSet_New(Py_None) == NULL, PyExc_TypeError);
    2425                 :            : 
    2426                 :            :     /* Raise TypeError for unhashable key */
    2427                 :            :     dup = PySet_New(ob);
    2428                 :            :     assertRaises(PySet_Discard(ob, dup) == -1, PyExc_TypeError);
    2429                 :            :     assertRaises(PySet_Contains(ob, dup) == -1, PyExc_TypeError);
    2430                 :            :     assertRaises(PySet_Add(ob, dup) == -1, PyExc_TypeError);
    2431                 :            : 
    2432                 :            :     /* Exercise successful pop, contains, add, and discard */
    2433                 :            :     elem = PySet_Pop(ob);
    2434                 :            :     assert(PySet_Contains(ob, elem) == 0);
    2435                 :            :     assert(PySet_GET_SIZE(ob) == 2);
    2436                 :            :     assert(PySet_Add(ob, elem) == 0);
    2437                 :            :     assert(PySet_Contains(ob, elem) == 1);
    2438                 :            :     assert(PySet_GET_SIZE(ob) == 3);
    2439                 :            :     assert(PySet_Discard(ob, elem) == 1);
    2440                 :            :     assert(PySet_GET_SIZE(ob) == 2);
    2441                 :            :     assert(PySet_Discard(ob, elem) == 0);
    2442                 :            :     assert(PySet_GET_SIZE(ob) == 2);
    2443                 :            : 
    2444                 :            :     /* Exercise clear */
    2445                 :            :     dup2 = PySet_New(dup);
    2446                 :            :     assert(PySet_Clear(dup2) == 0);
    2447                 :            :     assert(PySet_Size(dup2) == 0);
    2448                 :            :     Py_DECREF(dup2);
    2449                 :            : 
    2450                 :            :     /* Raise SystemError on clear or update of frozen set */
    2451                 :            :     f = PyFrozenSet_New(dup);
    2452                 :            :     assertRaises(PySet_Clear(f) == -1, PyExc_SystemError);
    2453                 :            :     assertRaises(_PySet_Update(f, dup) == -1, PyExc_SystemError);
    2454                 :            :     assert(PySet_Add(f, elem) == 0);
    2455                 :            :     Py_INCREF(f);
    2456                 :            :     assertRaises(PySet_Add(f, elem) == -1, PyExc_SystemError);
    2457                 :            :     Py_DECREF(f);
    2458                 :            :     Py_DECREF(f);
    2459                 :            : 
    2460                 :            :     /* Exercise direct iteration */
    2461                 :            :     i = 0, count = 0;
    2462                 :            :     while (_PySet_NextEntry((PyObject *)dup, &i, &x, &hash)) {
    2463                 :            :         s = PyUnicode_AsUTF8(x);
    2464                 :            :         assert(s && (s[0] == 'a' || s[0] == 'b' || s[0] == 'c'));
    2465                 :            :         count++;
    2466                 :            :     }
    2467                 :            :     assert(count == 3);
    2468                 :            : 
    2469                 :            :     /* Exercise updates */
    2470                 :            :     dup2 = PySet_New(NULL);
    2471                 :            :     assert(_PySet_Update(dup2, dup) == 0);
    2472                 :            :     assert(PySet_Size(dup2) == 3);
    2473                 :            :     assert(_PySet_Update(dup2, dup) == 0);
    2474                 :            :     assert(PySet_Size(dup2) == 3);
    2475                 :            :     Py_DECREF(dup2);
    2476                 :            : 
    2477                 :            :     /* Raise SystemError when self argument is not a set or frozenset. */
    2478                 :            :     t = PyTuple_New(0);
    2479                 :            :     assertRaises(PySet_Size(t) == -1, PyExc_SystemError);
    2480                 :            :     assertRaises(PySet_Contains(t, elem) == -1, PyExc_SystemError);
    2481                 :            :     Py_DECREF(t);
    2482                 :            : 
    2483                 :            :     /* Raise SystemError when self argument is not a set. */
    2484                 :            :     f = PyFrozenSet_New(dup);
    2485                 :            :     assert(PySet_Size(f) == 3);
    2486                 :            :     assert(PyFrozenSet_CheckExact(f));
    2487                 :            :     assertRaises(PySet_Discard(f, elem) == -1, PyExc_SystemError);
    2488                 :            :     assertRaises(PySet_Pop(f) == NULL, PyExc_SystemError);
    2489                 :            :     Py_DECREF(f);
    2490                 :            : 
    2491                 :            :     /* Raise KeyError when popping from an empty set */
    2492                 :            :     assert(PyNumber_InPlaceSubtract(ob, ob) == ob);
    2493                 :            :     Py_DECREF(ob);
    2494                 :            :     assert(PySet_GET_SIZE(ob) == 0);
    2495                 :            :     assertRaises(PySet_Pop(ob) == NULL, PyExc_KeyError);
    2496                 :            : 
    2497                 :            :     /* Restore the set from the copy using the PyNumber API */
    2498                 :            :     assert(PyNumber_InPlaceOr(ob, dup) == ob);
    2499                 :            :     Py_DECREF(ob);
    2500                 :            : 
    2501                 :            :     /* Verify constructors accept NULL arguments */
    2502                 :            :     f = PySet_New(NULL);
    2503                 :            :     assert(f != NULL);
    2504                 :            :     assert(PySet_GET_SIZE(f) == 0);
    2505                 :            :     Py_DECREF(f);
    2506                 :            :     f = PyFrozenSet_New(NULL);
    2507                 :            :     assert(f != NULL);
    2508                 :            :     assert(PyFrozenSet_CheckExact(f));
    2509                 :            :     assert(PySet_GET_SIZE(f) == 0);
    2510                 :            :     Py_DECREF(f);
    2511                 :            : 
    2512                 :            :     Py_DECREF(elem);
    2513                 :            :     Py_DECREF(dup);
    2514                 :            :     Py_RETURN_TRUE;
    2515                 :            : }
    2516                 :            : 
    2517                 :            : #undef assertRaises
    2518                 :            : 
    2519                 :            : #endif
    2520                 :            : 
    2521                 :            : /***** Dummy Struct  *************************************************/
    2522                 :            : 
    2523                 :            : static PyObject *
    2524                 :          0 : dummy_repr(PyObject *op)
    2525                 :            : {
    2526                 :          0 :     return PyUnicode_FromString("<dummy key>");
    2527                 :            : }
    2528                 :            : 
    2529                 :            : static void _Py_NO_RETURN
    2530                 :          0 : dummy_dealloc(PyObject* ignore)
    2531                 :            : {
    2532                 :            :     Py_FatalError("deallocating <dummy key>");
    2533                 :            : }
    2534                 :            : 
    2535                 :            : static PyTypeObject _PySetDummy_Type = {
    2536                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    2537                 :            :     "<dummy key> type",
    2538                 :            :     0,
    2539                 :            :     0,
    2540                 :            :     dummy_dealloc,      /*tp_dealloc*/ /*never called*/
    2541                 :            :     0,                  /*tp_vectorcall_offset*/
    2542                 :            :     0,                  /*tp_getattr*/
    2543                 :            :     0,                  /*tp_setattr*/
    2544                 :            :     0,                  /*tp_as_async*/
    2545                 :            :     dummy_repr,         /*tp_repr*/
    2546                 :            :     0,                  /*tp_as_number*/
    2547                 :            :     0,                  /*tp_as_sequence*/
    2548                 :            :     0,                  /*tp_as_mapping*/
    2549                 :            :     0,                  /*tp_hash */
    2550                 :            :     0,                  /*tp_call */
    2551                 :            :     0,                  /*tp_str */
    2552                 :            :     0,                  /*tp_getattro */
    2553                 :            :     0,                  /*tp_setattro */
    2554                 :            :     0,                  /*tp_as_buffer */
    2555                 :            :     Py_TPFLAGS_DEFAULT, /*tp_flags */
    2556                 :            : };
    2557                 :            : 
    2558                 :            : static PyObject _dummy_struct = {
    2559                 :            :   _PyObject_EXTRA_INIT
    2560                 :            :   2, &_PySetDummy_Type
    2561                 :            : };

Generated by: LCOV version 1.14