
/* set object implementation

   Written and maintained by Raymond D. Hettinger <python@rcn.com>
   Derived from Objects/dictobject.c.

   The basic lookup function used by all operations.
   This is based on Algorithm D from Knuth Vol. 3, Sec. 6.4.

   The initial probe index is computed as hash mod the table size.
   Subsequent probe indices are computed as explained in Objects/dictobject.c.

   To improve cache locality, each probe inspects a series of consecutive
   nearby entries before moving on to probes elsewhere in memory.  This leaves
   us with a hybrid of linear probing and randomized probing.  The linear probing
   reduces the cost of hash collisions because consecutive memory accesses
   tend to be much cheaper than scattered probes.  After LINEAR_PROBES steps,
   we then use more of the upper bits from the hash value and apply a simple
   linear congruential random number generator.  This helps break-up long
   chains of collisions.

   All arithmetic on hash should ignore overflow.

   Unlike the dictionary implementation, the lookkey function can return
   NULL if the rich comparison returns an error.

   Use cases for sets differ considerably from dictionaries where looked-up
   keys are more likely to be present.  In contrast, sets are primarily
   about membership testing where the presence of an element is not known in
   advance.  Accordingly, the set implementation needs to optimize for both
   the found and not-found case.
*/

#include "Python.h"
#include "pycore_ceval.h"               // _PyEval_GetBuiltin()
#include "pycore_critical_section.h"    // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
#include "pycore_dict.h"                // _PyDict_Contains_KnownHash()
#include "pycore_modsupport.h"          // _PyArg_NoKwnames()
#include "pycore_object.h"              // _PyObject_GC_UNTRACK()
#include "pycore_pyatomic_ft_wrappers.h"  // FT_ATOMIC_LOAD_SSIZE_RELAXED()
#include "pycore_pyerrors.h"            // _PyErr_SetKeyError()
#include "pycore_setobject.h"           // _PySet_NextEntry() definition

#include "stringlib/eq.h"               // unicode_eq()
#include <stddef.h>                     // offsetof()
#include "clinic/setobject.c.h"

/*[clinic input]
class set "PySetObject *" "&PySet_Type"
class frozenset "PySetObject *" "&PyFrozenSet_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=97ad1d3e9f117079]*/

/*[python input]
class setobject_converter(self_converter):
    type = "PySetObject *"
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=33a44506d4d57793]*/

/* Object used as dummy key to fill deleted entries */
static PyObject _dummy_struct;

#define dummy (&_dummy_struct)


/* ======================================================================== */
/* ======= Begin logic for probing the hash table ========================= */

/* Set this to zero to turn-off linear probing */
#ifndef LINEAR_PROBES
#define LINEAR_PROBES 9
#endif

/* This must be >= 1 */
#define PERTURB_SHIFT 5

static setentry *
set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *table;
    setentry *entry;
    size_t perturb = hash;
    size_t mask = so->mask;
    size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */
    int probes;
    int cmp;

    while (1) {
        entry = &so->table[i];
        probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
        do {
            if (entry->hash == 0 && entry->key == NULL)
                return entry;
            if (entry->hash == hash) {
                PyObject *startkey = entry->key;
                assert(startkey != dummy);
                if (startkey == key)
                    return entry;
                if (PyUnicode_CheckExact(startkey)
                    && PyUnicode_CheckExact(key)
                    && unicode_eq(startkey, key))
                    return entry;
                table = so->table;
                Py_INCREF(startkey);
                cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
                Py_DECREF(startkey);
                if (cmp < 0)
                    return NULL;
                if (table != so->table || entry->key != startkey)
                    return set_lookkey(so, key, hash);
                if (cmp > 0)
                    return entry;
                mask = so->mask;
            }
            entry++;
        } while (probes--);
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }
}

static int set_table_resize(PySetObject *, Py_ssize_t);

static int
set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *table;
    setentry *freeslot;
    setentry *entry;
    size_t perturb;
    size_t mask;
    size_t i;                       /* Unsigned for defined overflow behavior */
    int probes;
    int cmp;

    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);

    /* Pre-increment is necessary to prevent arbitrary code in the rich
       comparison from deallocating the key just before the insertion. */
    Py_INCREF(key);

  restart:

    mask = so->mask;
    i = (size_t)hash & mask;
    freeslot = NULL;
    perturb = hash;

    while (1) {
        entry = &so->table[i];
        probes = (i + LINEAR_PROBES <= mask) ? LINEAR_PROBES: 0;
        do {
            if (entry->hash == 0 && entry->key == NULL)
                goto found_unused_or_dummy;
            if (entry->hash == hash) {
                PyObject *startkey = entry->key;
                assert(startkey != dummy);
                if (startkey == key)
                    goto found_active;
                if (PyUnicode_CheckExact(startkey)
                    && PyUnicode_CheckExact(key)
                    && unicode_eq(startkey, key))
                    goto found_active;
                table = so->table;
                Py_INCREF(startkey);
                cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);
                Py_DECREF(startkey);
                if (cmp > 0)
                    goto found_active;
                if (cmp < 0)
                    goto comparison_error;
                if (table != so->table || entry->key != startkey)
                    goto restart;
                mask = so->mask;
            }
            else if (entry->hash == -1) {
                assert (entry->key == dummy);
                freeslot = entry;
            }
            entry++;
        } while (probes--);
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }

  found_unused_or_dummy:
    if (freeslot == NULL)
        goto found_unused;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
    freeslot->key = key;
    freeslot->hash = hash;
    return 0;

  found_unused:
    so->fill++;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
    entry->key = key;
    entry->hash = hash;
    if ((size_t)so->fill*5 < mask*3)
        return 0;
    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);

  found_active:
    Py_DECREF(key);
    return 0;

  comparison_error:
    Py_DECREF(key);
    return -1;
}

/*
Internal routine used by set_table_resize() to insert an item which is
known to be absent from the set.  Besides the performance benefit,
there is also safety benefit since using set_add_entry() risks making
a callback in the middle of a set_table_resize(), see issue 1456209.
The caller is responsible for updating the key's reference count and
the setobject's fill and used fields.
*/
static void
set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash)
{
    setentry *entry;
    size_t perturb = hash;
    size_t i = (size_t)hash & mask;
    size_t j;

    while (1) {
        entry = &table[i];
        if (entry->key == NULL)
            goto found_null;
        if (i + LINEAR_PROBES <= mask) {
            for (j = 0; j < LINEAR_PROBES; j++) {
                entry++;
                if (entry->key == NULL)
                    goto found_null;
            }
        }
        perturb >>= PERTURB_SHIFT;
        i = (i * 5 + 1 + perturb) & mask;
    }
  found_null:
    entry->key = key;
    entry->hash = hash;
}

/* ======== End logic for probing the hash table ========================== */
/* ======================================================================== */

/*
Restructure the table by allocating a new table and reinserting all
keys again.  When entries have been deleted, the new table may
actually be smaller than the old one.
*/
static int
set_table_resize(PySetObject *so, Py_ssize_t minused)
{
    setentry *oldtable, *newtable, *entry;
    Py_ssize_t oldmask = so->mask;
    size_t newmask;
    int is_oldtable_malloced;
    setentry small_copy[PySet_MINSIZE];

    assert(minused >= 0);

    /* Find the smallest table size > minused. */
    /* XXX speed-up with intrinsics */
    size_t newsize = PySet_MINSIZE;
    while (newsize <= (size_t)minused) {
        newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.
    }

    /* Get space for a new table. */
    oldtable = so->table;
    assert(oldtable != NULL);
    is_oldtable_malloced = oldtable != so->smalltable;

    if (newsize == PySet_MINSIZE) {
        /* A large table is shrinking, or we can't get any smaller. */
        newtable = so->smalltable;
        if (newtable == oldtable) {
            if (so->fill == so->used) {
                /* No dummies, so no point doing anything. */
                return 0;
            }
            /* We're not going to resize it, but rebuild the
               table anyway to purge old dummy entries.
               Subtle:  This is *necessary* if fill==size,
               as set_lookkey needs at least one virgin slot to
               terminate failing searches.  If fill < size, it's
               merely desirable, as dummies slow searches. */
            assert(so->fill > so->used);
            memcpy(small_copy, oldtable, sizeof(small_copy));
            oldtable = small_copy;
        }
    }
    else {
        newtable = PyMem_NEW(setentry, newsize);
        if (newtable == NULL) {
            PyErr_NoMemory();
            return -1;
        }
    }

    /* Make the set empty, using the new table. */
    assert(newtable != oldtable);
    memset(newtable, 0, sizeof(setentry) * newsize);
    so->mask = newsize - 1;
    so->table = newtable;

    /* Copy the data over; this is refcount-neutral for active entries;
       dummy entries aren't copied over, of course */
    newmask = (size_t)so->mask;
    if (so->fill == so->used) {
        for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
            if (entry->key != NULL) {
                set_insert_clean(newtable, newmask, entry->key, entry->hash);
            }
        }
    } else {
        so->fill = so->used;
        for (entry = oldtable; entry <= oldtable + oldmask; entry++) {
            if (entry->key != NULL && entry->key != dummy) {
                set_insert_clean(newtable, newmask, entry->key, entry->hash);
            }
        }
    }

    if (is_oldtable_malloced)
        PyMem_Free(oldtable);
    return 0;
}

static int
set_contains_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *entry;

    entry = set_lookkey(so, key, hash);
    if (entry != NULL)
        return entry->key != NULL;
    return -1;
}

#define DISCARD_NOTFOUND 0
#define DISCARD_FOUND 1

static int
set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
{
    setentry *entry;
    PyObject *old_key;

    entry = set_lookkey(so, key, hash);
    if (entry == NULL)
        return -1;
    if (entry->key == NULL)
        return DISCARD_NOTFOUND;
    old_key = entry->key;
    entry->key = dummy;
    entry->hash = -1;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
    Py_DECREF(old_key);
    return DISCARD_FOUND;
}

static int
set_add_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = _PyObject_HashFast(key);
    if (hash == -1) {
        return -1;
    }
    return set_add_entry(so, key, hash);
}

static int
set_contains_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = _PyObject_HashFast(key);
    if (hash == -1) {
        return -1;
    }
    return set_contains_entry(so, key, hash);
}

static int
set_discard_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash = _PyObject_HashFast(key);
    if (hash == -1) {
        return -1;
    }
    return set_discard_entry(so, key, hash);
}

static void
set_empty_to_minsize(PySetObject *so)
{
    memset(so->smalltable, 0, sizeof(so->smalltable));
    so->fill = 0;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, 0);
    so->mask = PySet_MINSIZE - 1;
    so->table = so->smalltable;
    so->hash = -1;
}

static int
set_clear_internal(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    setentry *entry;
    setentry *table = so->table;
    Py_ssize_t fill = so->fill;
    Py_ssize_t used = so->used;
    int table_is_malloced = table != so->smalltable;
    setentry small_copy[PySet_MINSIZE];

    assert (PyAnySet_Check(so));
    assert(table != NULL);

    /* This is delicate.  During the process of clearing the set,
     * decrefs can cause the set to mutate.  To avoid fatal confusion
     * (voice of experience), we have to make the set empty before
     * clearing the slots, and never refer to anything via so->ref while
     * clearing.
     */
    if (table_is_malloced)
        set_empty_to_minsize(so);

    else if (fill > 0) {
        /* It's a small table with something that needs to be cleared.
         * Afraid the only safe way is to copy the set entries into
         * another small table first.
         */
        memcpy(small_copy, table, sizeof(small_copy));
        table = small_copy;
        set_empty_to_minsize(so);
    }
    /* else it's a small table that's already empty */

    /* Now we can finally clear things.  If C had refcounts, we could
     * assert that the refcount on table is 1 now, i.e. that this function
     * has unique access to it, so decref side-effects can't alter it.
     */
    for (entry = table; used > 0; entry++) {
        if (entry->key && entry->key != dummy) {
            used--;
            Py_DECREF(entry->key);
        }
    }

    if (table_is_malloced)
        PyMem_Free(table);
    return 0;
}

/*
 * Iterate over a set table.  Use like so:
 *
 *     Py_ssize_t pos;
 *     setentry *entry;
 *     pos = 0;   # important!  pos should not otherwise be changed by you
 *     while (set_next(yourset, &pos, &entry)) {
 *              Refer to borrowed reference in entry->key.
 *     }
 *
 * CAUTION:  In general, it isn't safe to use set_next in a loop that
 * mutates the table.
 */
static int
set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr)
{
    Py_ssize_t i;
    Py_ssize_t mask;
    setentry *entry;

    assert (PyAnySet_Check(so));
    i = *pos_ptr;
    assert(i >= 0);
    mask = so->mask;
    entry = &so->table[i];
    while (i <= mask && (entry->key == NULL || entry->key == dummy)) {
        i++;
        entry++;
    }
    *pos_ptr = i+1;
    if (i > mask)
        return 0;
    assert(entry != NULL);
    *entry_ptr = entry;
    return 1;
}

static void
set_dealloc(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    setentry *entry;
    Py_ssize_t used = so->used;

    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyObject_GC_UnTrack(so);
    Py_TRASHCAN_BEGIN(so, set_dealloc)
    if (so->weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) so);

    for (entry = so->table; used > 0; entry++) {
        if (entry->key && entry->key != dummy) {
                used--;
                Py_DECREF(entry->key);
        }
    }
    if (so->table != so->smalltable)
        PyMem_Free(so->table);
    Py_TYPE(so)->tp_free(so);
    Py_TRASHCAN_END
}

static PyObject *
set_repr_lock_held(PySetObject *so)
{
    PyObject *result=NULL, *keys, *listrepr, *tmp;
    int status = Py_ReprEnter((PyObject*)so);

    if (status != 0) {
        if (status < 0)
            return NULL;
        return PyUnicode_FromFormat("%s(...)", Py_TYPE(so)->tp_name);
    }

    /* shortcut for the empty set */
    if (!so->used) {
        Py_ReprLeave((PyObject*)so);
        return PyUnicode_FromFormat("%s()", Py_TYPE(so)->tp_name);
    }

    keys = PySequence_List((PyObject *)so);
    if (keys == NULL)
        goto done;

    /* repr(keys)[1:-1] */
    listrepr = PyObject_Repr(keys);
    Py_DECREF(keys);
    if (listrepr == NULL)
        goto done;
    tmp = PyUnicode_Substring(listrepr, 1, PyUnicode_GET_LENGTH(listrepr)-1);
    Py_DECREF(listrepr);
    if (tmp == NULL)
        goto done;
    listrepr = tmp;

    if (!PySet_CheckExact(so))
        result = PyUnicode_FromFormat("%s({%U})",
                                      Py_TYPE(so)->tp_name,
                                      listrepr);
    else
        result = PyUnicode_FromFormat("{%U}", listrepr);
    Py_DECREF(listrepr);
done:
    Py_ReprLeave((PyObject*)so);
    return result;
}

static PyObject *
set_repr(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(so);
    result = set_repr_lock_held(so);
    Py_END_CRITICAL_SECTION();
    return result;
}

static Py_ssize_t
set_len(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    return FT_ATOMIC_LOAD_SSIZE_RELAXED(so->used);
}

static int
set_merge_lock_held(PySetObject *so, PyObject *otherset)
{
    PySetObject *other;
    PyObject *key;
    Py_ssize_t i;
    setentry *so_entry;
    setentry *other_entry;

    assert (PyAnySet_Check(so));
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(otherset);

    other = _PySet_CAST(otherset);
    if (other == so || other->used == 0)
        /* a.update(a) or a.update(set()); nothing to do */
        return 0;
    /* Do one big resize at the start, rather than
     * incrementally resizing as we insert new keys.  Expect
     * that there will be no (or few) overlapping keys.
     */
    if ((so->fill + other->used)*5 >= so->mask*3) {
        if (set_table_resize(so, (so->used + other->used)*2) != 0)
            return -1;
    }
    so_entry = so->table;
    other_entry = other->table;

    /* If our table is empty, and both tables have the same size, and
       there are no dummies to eliminate, then just copy the pointers. */
    if (so->fill == 0 && so->mask == other->mask && other->fill == other->used) {
        for (i = 0; i <= other->mask; i++, so_entry++, other_entry++) {
            key = other_entry->key;
            if (key != NULL) {
                assert(so_entry->key == NULL);
                so_entry->key = Py_NewRef(key);
                so_entry->hash = other_entry->hash;
            }
        }
        so->fill = other->fill;
        FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
        return 0;
    }

    /* If our table is empty, we can use set_insert_clean() */
    if (so->fill == 0) {
        setentry *newtable = so->table;
        size_t newmask = (size_t)so->mask;
        so->fill = other->used;
        FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
        for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
            key = other_entry->key;
            if (key != NULL && key != dummy) {
                set_insert_clean(newtable, newmask, Py_NewRef(key),
                                 other_entry->hash);
            }
        }
        return 0;
    }

    /* We can't assure there are no duplicates, so do normal insertions */
    for (i = 0; i <= other->mask; i++) {
        other_entry = &other->table[i];
        key = other_entry->key;
        if (key != NULL && key != dummy) {
            if (set_add_entry(so, key, other_entry->hash))
                return -1;
        }
    }
    return 0;
}

/*[clinic input]
@critical_section
set.pop
    so: setobject

Remove and return an arbitrary set element.

Raises KeyError if the set is empty.
[clinic start generated code]*/

static PyObject *
set_pop_impl(PySetObject *so)
/*[clinic end generated code: output=4d65180f1271871b input=9296c84921125060]*/
{
    /* Make sure the search finger is in bounds */
    setentry *entry = so->table + (so->finger & so->mask);
    setentry *limit = so->table + so->mask;
    PyObject *key;

    if (so->used == 0) {
        PyErr_SetString(PyExc_KeyError, "pop from an empty set");
        return NULL;
    }
    while (entry->key == NULL || entry->key==dummy) {
        entry++;
        if (entry > limit)
            entry = so->table;
    }
    key = entry->key;
    entry->key = dummy;
    entry->hash = -1;
    FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
    so->finger = entry - so->table + 1;   /* next place to start */
    return key;
}

static int
set_traverse(PyObject *self, visitproc visit, void *arg)
{
    PySetObject *so = _PySet_CAST(self);
    Py_ssize_t pos = 0;
    setentry *entry;

    while (set_next(so, &pos, &entry))
        Py_VISIT(entry->key);
    return 0;
}

/* Work to increase the bit dispersion for closely spaced hash values.
   This is important because some use cases have many combinations of a
   small number of elements with nearby hashes so that many distinct
   combinations collapse to only a handful of distinct hash values. */

static Py_uhash_t
_shuffle_bits(Py_uhash_t h)
{
    return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
}

/* Most of the constants in this hash algorithm are randomly chosen
   large primes with "interesting bit patterns" and that passed tests
   for good collision statistics on a variety of problematic datasets
   including powersets and graph structures (such as David Eppstein's
   graph recipes in Lib/test/test_set.py).

   This hash algorithm can be used on either a frozenset or a set.
   When it is used on a set, it computes the hash value of the equivalent
   frozenset without creating a new frozenset object. */

static Py_hash_t
frozenset_hash_impl(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    Py_uhash_t hash = 0;
    setentry *entry;

    /* Xor-in shuffled bits from every entry's hash field because xor is
       commutative and a frozenset hash should be independent of order.

       For speed, include null entries and dummy entries and then
       subtract out their effect afterwards so that the final hash
       depends only on active entries.  This allows the code to be
       vectorized by the compiler and it saves the unpredictable
       branches that would arise when trying to exclude null and dummy
       entries on every iteration. */

    for (entry = so->table; entry <= &so->table[so->mask]; entry++)
        hash ^= _shuffle_bits(entry->hash);

    /* Remove the effect of an odd number of NULL entries */
    if ((so->mask + 1 - so->fill) & 1)
        hash ^= _shuffle_bits(0);

    /* Remove the effect of an odd number of dummy entries */
    if ((so->fill - so->used) & 1)
        hash ^= _shuffle_bits(-1);

    /* Factor in the number of active entries */
    hash ^= ((Py_uhash_t)PySet_GET_SIZE(self) + 1) * 1927868237UL;

    /* Disperse patterns arising in nested frozensets */
    hash ^= (hash >> 11) ^ (hash >> 25);
    hash = hash * 69069U + 907133923UL;

    /* -1 is reserved as an error code */
    if (hash == (Py_uhash_t)-1)
        hash = 590923713UL;

    return (Py_hash_t)hash;
}

static Py_hash_t
frozenset_hash(PyObject *self)
{
    PySetObject *so = _PySet_CAST(self);
    Py_uhash_t hash;

    if (so->hash != -1) {
        return so->hash;
    }

    hash = frozenset_hash_impl(self);
    so->hash = hash;
    return hash;
}

/***** Set iterator type ***********************************************/

typedef struct {
    PyObject_HEAD
    PySetObject *si_set; /* Set to NULL when iterator is exhausted */
    Py_ssize_t si_used;
    Py_ssize_t si_pos;
    Py_ssize_t len;
} setiterobject;

static void
setiter_dealloc(PyObject *self)
{
    setiterobject *si = (setiterobject*)self;
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    _PyObject_GC_UNTRACK(si);
    Py_XDECREF(si->si_set);
    PyObject_GC_Del(si);
}

static int
setiter_traverse(PyObject *self, visitproc visit, void *arg)
{
    setiterobject *si = (setiterobject*)self;
    Py_VISIT(si->si_set);
    return 0;
}

static PyObject *
setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored))
{
    Py_ssize_t len = 0;
    if (si->si_set != NULL && si->si_used == si->si_set->used)
        len = si->len;
    return PyLong_FromSsize_t(len);
}

PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");

static PyObject *
setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
{
    /* copy the iterator state */
    setiterobject tmp = *si;
    Py_XINCREF(tmp.si_set);

    /* iterate the temporary into a list */
    PyObject *list = PySequence_List((PyObject*)&tmp);
    Py_XDECREF(tmp.si_set);
    if (list == NULL) {
        return NULL;
    }
    return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), list);
}

PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");

static PyMethodDef setiter_methods[] = {
    {"__length_hint__", (PyCFunction)setiter_len, METH_NOARGS, length_hint_doc},
    {"__reduce__", (PyCFunction)setiter_reduce, METH_NOARGS, reduce_doc},
    {NULL,              NULL}           /* sentinel */
};

static PyObject *setiter_iternext(PyObject *self)
{
    setiterobject *si = (setiterobject*)self;
    PyObject *key = NULL;
    Py_ssize_t i, mask;
    setentry *entry;
    PySetObject *so = si->si_set;

    if (so == NULL)
        return NULL;
    assert (PyAnySet_Check(so));

    Py_ssize_t so_used = FT_ATOMIC_LOAD_SSIZE(so->used);
    Py_ssize_t si_used = FT_ATOMIC_LOAD_SSIZE(si->si_used);
    if (si_used != so_used) {
        PyErr_SetString(PyExc_RuntimeError,
                        "Set changed size during iteration");
        si->si_used = -1; /* Make this state sticky */
        return NULL;
    }

    Py_BEGIN_CRITICAL_SECTION(so);
    i = si->si_pos;
    assert(i>=0);
    entry = so->table;
    mask = so->mask;
    while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy)) {
        i++;
    }
    if (i <= mask) {
        key = Py_NewRef(entry[i].key);
    }
    Py_END_CRITICAL_SECTION();
    si->si_pos = i+1;
    if (key == NULL) {
        si->si_set = NULL;
        Py_DECREF(so);
        return NULL;
    }
    si->len--;
    return key;
}

PyTypeObject PySetIter_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "set_iterator",                             /* tp_name */
    sizeof(setiterobject),                      /* tp_basicsize */
    0,                                          /* tp_itemsize */
    /* methods */
    setiter_dealloc,                            /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    0,                                          /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,    /* tp_flags */
    0,                                          /* tp_doc */
    setiter_traverse,                           /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    PyObject_SelfIter,                          /* tp_iter */
    setiter_iternext,                           /* tp_iternext */
    setiter_methods,                            /* tp_methods */
    0,
};

static PyObject *
set_iter(PyObject *so)
{
    Py_ssize_t size = set_len(so);
    setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
    if (si == NULL)
        return NULL;
    si->si_set = (PySetObject*)Py_NewRef(so);
    si->si_used = size;
    si->si_pos = 0;
    si->len = size;
    _PyObject_GC_TRACK(si);
    return (PyObject *)si;
}

static int
set_update_dict_lock_held(PySetObject *so, PyObject *other)
{
    assert(PyDict_CheckExact(other));

    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    /* Do one big resize at the start, rather than
    * incrementally resizing as we insert new keys.  Expect
    * that there will be no (or few) overlapping keys.
    */
    Py_ssize_t dictsize = PyDict_GET_SIZE(other);
    if ((so->fill + dictsize)*5 >= so->mask*3) {
        if (set_table_resize(so, (so->used + dictsize)*2) != 0) {
            return -1;
        }
    }

    Py_ssize_t pos = 0;
    PyObject *key;
    PyObject *value;
    Py_hash_t hash;
    while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
        if (set_add_entry(so, key, hash)) {
            return -1;
        }
    }
    return 0;
}

static int
set_update_iterable_lock_held(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);

    PyObject *it = PyObject_GetIter(other);
    if (it == NULL) {
        return -1;
    }

    PyObject *key;
    while ((key = PyIter_Next(it)) != NULL) {
        if (set_add_key(so, key)) {
            Py_DECREF(it);
            Py_DECREF(key);
            return -1;
        }
        Py_DECREF(key);
    }
    Py_DECREF(it);
    if (PyErr_Occurred())
        return -1;
    return 0;
}

static int
set_update_lock_held(PySetObject *so, PyObject *other)
{
    if (PyAnySet_Check(other)) {
        return set_merge_lock_held(so, other);
    }
    else if (PyDict_CheckExact(other)) {
        return set_update_dict_lock_held(so, other);
    }
    return set_update_iterable_lock_held(so, other);
}

// set_update for a `so` that is only visible to the current thread
static int
set_update_local(PySetObject *so, PyObject *other)
{
    assert(Py_REFCNT(so) == 1);
    if (PyAnySet_Check(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_merge_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
    else if (PyDict_CheckExact(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_update_dict_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
    return set_update_iterable_lock_held(so, other);
}

static int
set_update_internal(PySetObject *so, PyObject *other)
{
    if (PyAnySet_Check(other)) {
        if (Py_Is((PyObject *)so, other)) {
            return 0;
        }
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_merge_lock_held(so, other);
        Py_END_CRITICAL_SECTION2();
        return rv;
    }
    else if (PyDict_CheckExact(other)) {
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_update_dict_lock_held(so, other);
        Py_END_CRITICAL_SECTION2();
        return rv;
    }
    else {
        int rv;
        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_update_iterable_lock_held(so, other);
        Py_END_CRITICAL_SECTION();
        return rv;
    }
}

/*[clinic input]
set.update
    so: setobject
    *others: array

Update the set, adding elements from all others.
[clinic start generated code]*/

static PyObject *
set_update_impl(PySetObject *so, PyObject * const *others,
                Py_ssize_t others_length)
/*[clinic end generated code: output=017c781c992d5c23 input=ed5d78885b076636]*/
{
    Py_ssize_t i;

    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        if (set_update_internal(so, other))
            return NULL;
    }
    Py_RETURN_NONE;
}

/* XXX Todo:
   If aligned memory allocations become available, make the
   set object 64 byte aligned so that most of the fields
   can be retrieved or updated in a single cache line.
*/

static PyObject *
make_new_set(PyTypeObject *type, PyObject *iterable)
{
    assert(PyType_Check(type));
    PySetObject *so;

    so = (PySetObject *)type->tp_alloc(type, 0);
    if (so == NULL)
        return NULL;

    so->fill = 0;
    so->used = 0;
    so->mask = PySet_MINSIZE - 1;
    so->table = so->smalltable;
    so->hash = -1;
    so->finger = 0;
    so->weakreflist = NULL;

    if (iterable != NULL) {
        if (set_update_local(so, iterable)) {
            Py_DECREF(so);
            return NULL;
        }
    }

    return (PyObject *)so;
}

static PyObject *
make_new_set_basetype(PyTypeObject *type, PyObject *iterable)
{
    if (type != &PySet_Type && type != &PyFrozenSet_Type) {
        if (PyType_IsSubtype(type, &PySet_Type))
            type = &PySet_Type;
        else
            type = &PyFrozenSet_Type;
    }
    return make_new_set(type, iterable);
}

static PyObject *
make_new_frozenset(PyTypeObject *type, PyObject *iterable)
{
    if (type != &PyFrozenSet_Type) {
        return make_new_set(type, iterable);
    }

    if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) {
        /* frozenset(f) is idempotent */
        return Py_NewRef(iterable);
    }
    return make_new_set(type, iterable);
}

static PyObject *
frozenset_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *iterable = NULL;

    if ((type == &PyFrozenSet_Type ||
         type->tp_init == PyFrozenSet_Type.tp_init) &&
        !_PyArg_NoKeywords("frozenset", kwds)) {
        return NULL;
    }

    if (!PyArg_UnpackTuple(args, type->tp_name, 0, 1, &iterable)) {
        return NULL;
    }

    return make_new_frozenset(type, iterable);
}

static PyObject *
frozenset_vectorcall(PyObject *type, PyObject * const*args,
                     size_t nargsf, PyObject *kwnames)
{
    if (!_PyArg_NoKwnames("frozenset", kwnames)) {
        return NULL;
    }

    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    if (!_PyArg_CheckPositional("frozenset", nargs, 0, 1)) {
        return NULL;
    }

    PyObject *iterable = (nargs ? args[0] : NULL);
    return make_new_frozenset(_PyType_CAST(type), iterable);
}

static PyObject *
set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    return make_new_set(type, NULL);
}

/* set_swap_bodies() switches the contents of any two sets by moving their
   internal data pointers and, if needed, copying the internal smalltables.
   Semantically equivalent to:

     t=set(a); a.clear(); a.update(b); b.clear(); b.update(t); del t

   The function always succeeds and it leaves both objects in a stable state.
   Useful for operations that update in-place (by allowing an intermediate
   result to be swapped into one of the original inputs).
*/

static void
set_swap_bodies(PySetObject *a, PySetObject *b)
{
    Py_ssize_t t;
    setentry *u;
    setentry tab[PySet_MINSIZE];
    Py_hash_t h;

    t = a->fill;     a->fill   = b->fill;        b->fill  = t;
    t = a->used;
    FT_ATOMIC_STORE_SSIZE_RELAXED(a->used, b->used);
    FT_ATOMIC_STORE_SSIZE_RELAXED(b->used, t);
    t = a->mask;     a->mask   = b->mask;        b->mask  = t;

    u = a->table;
    if (a->table == a->smalltable)
        u = b->smalltable;
    a->table  = b->table;
    if (b->table == b->smalltable)
        a->table = a->smalltable;
    b->table = u;

    if (a->table == a->smalltable || b->table == b->smalltable) {
        memcpy(tab, a->smalltable, sizeof(tab));
        memcpy(a->smalltable, b->smalltable, sizeof(tab));
        memcpy(b->smalltable, tab, sizeof(tab));
    }

    if (PyType_IsSubtype(Py_TYPE(a), &PyFrozenSet_Type)  &&
        PyType_IsSubtype(Py_TYPE(b), &PyFrozenSet_Type)) {
        h = a->hash;     a->hash = b->hash;  b->hash = h;
    } else {
        a->hash = -1;
        b->hash = -1;
    }
}

/*[clinic input]
@critical_section
set.copy
    so: setobject

Return a shallow copy of a set.
[clinic start generated code]*/

static PyObject *
set_copy_impl(PySetObject *so)
/*[clinic end generated code: output=c9223a1e1cc6b041 input=c169a4fbb8209257]*/
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    PyObject *copy = make_new_set_basetype(Py_TYPE(so), NULL);
    if (copy == NULL) {
        return NULL;
    }
    if (set_merge_lock_held((PySetObject *)copy, (PyObject *)so) < 0) {
        Py_DECREF(copy);
        return NULL;
    }
    return copy;
}

/*[clinic input]
@critical_section
frozenset.copy
    so: setobject

Return a shallow copy of a set.
[clinic start generated code]*/

static PyObject *
frozenset_copy_impl(PySetObject *so)
/*[clinic end generated code: output=b356263526af9e70 input=fbf5bef131268dd7]*/
{
    if (PyFrozenSet_CheckExact(so)) {
        return Py_NewRef(so);
    }
    return set_copy_impl(so);
}

/*[clinic input]
@critical_section
set.clear
    so: setobject

Remove all elements from this set.
[clinic start generated code]*/

static PyObject *
set_clear_impl(PySetObject *so)
/*[clinic end generated code: output=4e71d5a83904161a input=c6f831b366111950]*/
{
    set_clear_internal((PyObject*)so);
    Py_RETURN_NONE;
}

/*[clinic input]
set.union
    so: setobject
    *others: array

Return a new set with elements from the set and all others.
[clinic start generated code]*/

static PyObject *
set_union_impl(PySetObject *so, PyObject * const *others,
               Py_ssize_t others_length)
/*[clinic end generated code: output=b1bfa3d74065f27e input=55a2e81db6347a4f]*/
{
    PySetObject *result;
    PyObject *other;
    Py_ssize_t i;

    result = (PySetObject *)set_copy(so, NULL);
    if (result == NULL)
        return NULL;

    for (i = 0; i < others_length; i++) {
        other = others[i];
        if ((PyObject *)so == other)
            continue;
        if (set_update_local(result, other)) {
            Py_DECREF(result);
            return NULL;
        }
    }
    return (PyObject *)result;
}

static PyObject *
set_or(PyObject *self, PyObject *other)
{
    PySetObject *result;

    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    result = (PySetObject *)set_copy(so, NULL);
    if (result == NULL) {
        return NULL;
    }
    if (Py_Is((PyObject *)so, other)) {
        return (PyObject *)result;
    }
    if (set_update_local(result, other)) {
        Py_DECREF(result);
        return NULL;
    }
    return (PyObject *)result;
}

static PyObject *
set_ior(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    if (set_update_internal(so, other)) {
        return NULL;
    }
    return Py_NewRef(so);
}

static PyObject *
set_intersection(PySetObject *so, PyObject *other)
{
    PySetObject *result;
    PyObject *key, *it, *tmp;
    Py_hash_t hash;
    int rv;

    if ((PyObject *)so == other)
        return set_copy_impl(so);

    result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
    if (result == NULL)
        return NULL;

    if (PyAnySet_Check(other)) {
        Py_ssize_t pos = 0;
        setentry *entry;

        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
            tmp = (PyObject *)so;
            so = (PySetObject *)other;
            other = tmp;
        }

        while (set_next((PySetObject *)other, &pos, &entry)) {
            key = entry->key;
            hash = entry->hash;
            Py_INCREF(key);
            rv = set_contains_entry(so, key, hash);
            if (rv < 0) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
            if (rv) {
                if (set_add_entry(result, key, hash)) {
                    Py_DECREF(result);
                    Py_DECREF(key);
                    return NULL;
                }
            }
            Py_DECREF(key);
        }
        return (PyObject *)result;
    }

    it = PyObject_GetIter(other);
    if (it == NULL) {
        Py_DECREF(result);
        return NULL;
    }

    while ((key = PyIter_Next(it)) != NULL) {
        hash = PyObject_Hash(key);
        if (hash == -1)
            goto error;
        rv = set_contains_entry(so, key, hash);
        if (rv < 0)
            goto error;
        if (rv) {
            if (set_add_entry(result, key, hash))
                goto error;
            if (PySet_GET_SIZE(result) >= PySet_GET_SIZE(so)) {
                Py_DECREF(key);
                break;
            }
        }
        Py_DECREF(key);
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        Py_DECREF(result);
        return NULL;
    }
    return (PyObject *)result;
  error:
    Py_DECREF(it);
    Py_DECREF(result);
    Py_DECREF(key);
    return NULL;
}

/*[clinic input]
set.intersection as set_intersection_multi
    so: setobject
    *others: array

Return a new set with elements common to the set and all others.
[clinic start generated code]*/

static PyObject *
set_intersection_multi_impl(PySetObject *so, PyObject * const *others,
                            Py_ssize_t others_length)
/*[clinic end generated code: output=db9ff9f875132b6b input=36c7b615694cadae]*/
{
    Py_ssize_t i;

    if (others_length == 0) {
        return set_copy(so, NULL);
    }

    PyObject *result = Py_NewRef(so);
    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        PyObject *newresult;
        Py_BEGIN_CRITICAL_SECTION2(result, other);
        newresult = set_intersection((PySetObject *)result, other);
        Py_END_CRITICAL_SECTION2();
        if (newresult == NULL) {
            Py_DECREF(result);
            return NULL;
        }
        Py_SETREF(result, newresult);
    }
    return result;
}

static PyObject *
set_intersection_update(PySetObject *so, PyObject *other)
{
    PyObject *tmp;

    tmp = set_intersection(so, other);
    if (tmp == NULL)
        return NULL;
    set_swap_bodies(so, (PySetObject *)tmp);
    Py_DECREF(tmp);
    Py_RETURN_NONE;
}

/*[clinic input]
set.intersection_update as set_intersection_update_multi
    so: setobject
    *others: array

Update the set, keeping only elements found in it and all others.
[clinic start generated code]*/

static PyObject *
set_intersection_update_multi_impl(PySetObject *so, PyObject * const *others,
                                   Py_ssize_t others_length)
/*[clinic end generated code: output=d768b5584675b48d input=782e422fc370e4fc]*/
{
    PyObject *tmp;

    tmp = set_intersection_multi_impl(so, others, others_length);
    if (tmp == NULL)
        return NULL;
    Py_BEGIN_CRITICAL_SECTION(so);
    set_swap_bodies(so, (PySetObject *)tmp);
    Py_END_CRITICAL_SECTION();
    Py_DECREF(tmp);
    Py_RETURN_NONE;
}

static PyObject *
set_and(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    PyObject *rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_intersection(so, other);
    Py_END_CRITICAL_SECTION2();

    return rv;
}

static PyObject *
set_iand(PyObject *self, PyObject *other)
{
    PyObject *result;

    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    Py_BEGIN_CRITICAL_SECTION2(so, other);
    result = set_intersection_update(so, other);
    Py_END_CRITICAL_SECTION2();

    if (result == NULL)
        return NULL;
    Py_DECREF(result);
    return Py_NewRef(so);
}

/*[clinic input]
@critical_section so other
set.isdisjoint
    so: setobject
    other: object
    /

Return True if two sets have a null intersection.
[clinic start generated code]*/

static PyObject *
set_isdisjoint_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=273493f2d57c565e input=32f8dcab5e0fc7d6]*/
{
    PyObject *key, *it, *tmp;
    int rv;

    if ((PyObject *)so == other) {
        if (PySet_GET_SIZE(so) == 0)
            Py_RETURN_TRUE;
        else
            Py_RETURN_FALSE;
    }

    if (PyAnySet_CheckExact(other)) {
        Py_ssize_t pos = 0;
        setentry *entry;

        if (PySet_GET_SIZE(other) > PySet_GET_SIZE(so)) {
            tmp = (PyObject *)so;
            so = (PySetObject *)other;
            other = tmp;
        }
        while (set_next((PySetObject *)other, &pos, &entry)) {
            PyObject *key = entry->key;
            Py_INCREF(key);
            rv = set_contains_entry(so, key, entry->hash);
            Py_DECREF(key);
            if (rv < 0) {
                return NULL;
            }
            if (rv) {
                Py_RETURN_FALSE;
            }
        }
        Py_RETURN_TRUE;
    }

    it = PyObject_GetIter(other);
    if (it == NULL)
        return NULL;

    while ((key = PyIter_Next(it)) != NULL) {
        rv = set_contains_key(so, key);
        Py_DECREF(key);
        if (rv < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (rv) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred())
        return NULL;
    Py_RETURN_TRUE;
}

static int
set_difference_update_internal(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    if ((PyObject *)so == other)
        return set_clear_internal((PyObject*)so);

    if (PyAnySet_Check(other)) {
        setentry *entry;
        Py_ssize_t pos = 0;

        /* Optimization:  When the other set is more than 8 times
           larger than the base set, replace the other set with
           intersection of the two sets.
        */
        if ((PySet_GET_SIZE(other) >> 3) > PySet_GET_SIZE(so)) {
            other = set_intersection(so, other);
            if (other == NULL)
                return -1;
        } else {
            Py_INCREF(other);
        }

        while (set_next((PySetObject *)other, &pos, &entry)) {
            PyObject *key = entry->key;
            Py_INCREF(key);
            if (set_discard_entry(so, key, entry->hash) < 0) {
                Py_DECREF(other);
                Py_DECREF(key);
                return -1;
            }
            Py_DECREF(key);
        }

        Py_DECREF(other);
    } else {
        PyObject *key, *it;
        it = PyObject_GetIter(other);
        if (it == NULL)
            return -1;

        while ((key = PyIter_Next(it)) != NULL) {
            if (set_discard_key(so, key) < 0) {
                Py_DECREF(it);
                Py_DECREF(key);
                return -1;
            }
            Py_DECREF(key);
        }
        Py_DECREF(it);
        if (PyErr_Occurred())
            return -1;
    }
    /* If more than 1/4th are dummies, then resize them away. */
    if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
        return 0;
    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
}

/*[clinic input]
set.difference_update
    so: setobject
    *others: array

Update the set, removing elements found in others.
[clinic start generated code]*/

static PyObject *
set_difference_update_impl(PySetObject *so, PyObject * const *others,
                           Py_ssize_t others_length)
/*[clinic end generated code: output=04a22179b322cfe6 input=93ac28ba5b233696]*/
{
    Py_ssize_t i;

    for (i = 0; i < others_length; i++) {
        PyObject *other = others[i];
        int rv;
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_difference_update_internal(so, other);
        Py_END_CRITICAL_SECTION2();
        if (rv) {
            return NULL;
        }
    }
    Py_RETURN_NONE;
}

static PyObject *
set_copy_and_difference(PySetObject *so, PyObject *other)
{
    PyObject *result;

    result = set_copy_impl(so);
    if (result == NULL)
        return NULL;
    if (set_difference_update_internal((PySetObject *) result, other) == 0)
        return result;
    Py_DECREF(result);
    return NULL;
}

static PyObject *
set_difference(PySetObject *so, PyObject *other)
{
    PyObject *result;
    PyObject *key;
    Py_hash_t hash;
    setentry *entry;
    Py_ssize_t pos = 0, other_size;
    int rv;

    if (PyAnySet_Check(other)) {
        other_size = PySet_GET_SIZE(other);
    }
    else if (PyDict_CheckExact(other)) {
        other_size = PyDict_GET_SIZE(other);
    }
    else {
        return set_copy_and_difference(so, other);
    }

    /* If len(so) much more than len(other), it's more efficient to simply copy
     * so and then iterate other looking for common elements. */
    if ((PySet_GET_SIZE(so) >> 2) > other_size) {
        return set_copy_and_difference(so, other);
    }

    result = make_new_set_basetype(Py_TYPE(so), NULL);
    if (result == NULL)
        return NULL;

    if (PyDict_CheckExact(other)) {
        while (set_next(so, &pos, &entry)) {
            key = entry->key;
            hash = entry->hash;
            Py_INCREF(key);
            rv = _PyDict_Contains_KnownHash(other, key, hash);
            if (rv < 0) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
            if (!rv) {
                if (set_add_entry((PySetObject *)result, key, hash)) {
                    Py_DECREF(result);
                    Py_DECREF(key);
                    return NULL;
                }
            }
            Py_DECREF(key);
        }
        return result;
    }

    /* Iterate over so, checking for common elements in other. */
    while (set_next(so, &pos, &entry)) {
        key = entry->key;
        hash = entry->hash;
        Py_INCREF(key);
        rv = set_contains_entry((PySetObject *)other, key, hash);
        if (rv < 0) {
            Py_DECREF(result);
            Py_DECREF(key);
            return NULL;
        }
        if (!rv) {
            if (set_add_entry((PySetObject *)result, key, hash)) {
                Py_DECREF(result);
                Py_DECREF(key);
                return NULL;
            }
        }
        Py_DECREF(key);
    }
    return result;
}

/*[clinic input]
set.difference as set_difference_multi
    so: setobject
    *others: array

Return a new set with elements in the set that are not in the others.
[clinic start generated code]*/

static PyObject *
set_difference_multi_impl(PySetObject *so, PyObject * const *others,
                          Py_ssize_t others_length)
/*[clinic end generated code: output=b0d33fb05d5477a7 input=c1eb448d483416ad]*/
{
    Py_ssize_t i;
    PyObject *result, *other;

    if (others_length == 0) {
        return set_copy(so, NULL);
    }

    other = others[0];
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    result = set_difference(so, other);
    Py_END_CRITICAL_SECTION2();
    if (result == NULL)
        return NULL;

    for (i = 1; i < others_length; i++) {
        other = others[i];
        int rv;
        Py_BEGIN_CRITICAL_SECTION(other);
        rv = set_difference_update_internal((PySetObject *)result, other);
        Py_END_CRITICAL_SECTION();
        if (rv) {
            Py_DECREF(result);
            return NULL;
        }
    }
    return result;
}

static PyObject *
set_sub(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    PyObject *rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_difference(so, other);
    Py_END_CRITICAL_SECTION2();
    return rv;
}

static PyObject *
set_isub(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    int rv;
    Py_BEGIN_CRITICAL_SECTION2(so, other);
    rv = set_difference_update_internal(so, other);
    Py_END_CRITICAL_SECTION2();
    if (rv < 0) {
        return NULL;
    }
    return Py_NewRef(so);
}

static int
set_symmetric_difference_update_dict(PySetObject *so, PyObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    Py_ssize_t pos = 0;
    PyObject *key, *value;
    Py_hash_t hash;
    while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
        Py_INCREF(key);
        int rv = set_discard_entry(so, key, hash);
        if (rv < 0) {
            Py_DECREF(key);
            return -1;
        }
        if (rv == DISCARD_NOTFOUND) {
            if (set_add_entry(so, key, hash)) {
                Py_DECREF(key);
                return -1;
            }
        }
        Py_DECREF(key);
    }
    return 0;
}

static int
set_symmetric_difference_update_set(PySetObject *so, PySetObject *other)
{
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(so);
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(other);

    Py_ssize_t pos = 0;
    setentry *entry;
    while (set_next(other, &pos, &entry)) {
        PyObject *key = Py_NewRef(entry->key);
        Py_hash_t hash = entry->hash;
        int rv = set_discard_entry(so, key, hash);
        if (rv < 0) {
            Py_DECREF(key);
            return -1;
        }
        if (rv == DISCARD_NOTFOUND) {
            if (set_add_entry(so, key, hash)) {
                Py_DECREF(key);
                return -1;
            }
        }
        Py_DECREF(key);
    }
    return 0;
}

/*[clinic input]
set.symmetric_difference_update
    so: setobject
    other: object
    /

Update the set, keeping only elements found in either set, but not in both.
[clinic start generated code]*/

static PyObject *
set_symmetric_difference_update(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=fbb049c0806028de input=a50acf0365e1f0a5]*/
{
    if (Py_Is((PyObject *)so, other)) {
        return set_clear(so, NULL);
    }

    int rv;
    if (PyDict_CheckExact(other)) {
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_symmetric_difference_update_dict(so, other);
        Py_END_CRITICAL_SECTION2();
    }
    else if (PyAnySet_Check(other)) {
        Py_BEGIN_CRITICAL_SECTION2(so, other);
        rv = set_symmetric_difference_update_set(so, (PySetObject *)other);
        Py_END_CRITICAL_SECTION2();
    }
    else {
        PySetObject *otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other);
        if (otherset == NULL) {
            return NULL;
        }

        Py_BEGIN_CRITICAL_SECTION(so);
        rv = set_symmetric_difference_update_set(so, otherset);
        Py_END_CRITICAL_SECTION();

        Py_DECREF(otherset);
    }
    if (rv < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@critical_section so other
set.symmetric_difference
    so: setobject
    other: object
    /

Return a new set with elements in either the set or other but not both.
[clinic start generated code]*/

static PyObject *
set_symmetric_difference_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=270ee0b5d42b0797 input=624f6e7bbdf70db1]*/
{
    PySetObject *result = (PySetObject *)make_new_set_basetype(Py_TYPE(so), NULL);
    if (result == NULL) {
        return NULL;
    }
    if (set_update_lock_held(result, other) < 0) {
        Py_DECREF(result);
        return NULL;
    }
    if (set_symmetric_difference_update_set(result, so) < 0) {
        Py_DECREF(result);
        return NULL;
    }
    return (PyObject *)result;
}

static PyObject *
set_xor(PyObject *self, PyObject *other)
{
    if (!PyAnySet_Check(self) || !PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);
    return set_symmetric_difference(so, other);
}

static PyObject *
set_ixor(PyObject *self, PyObject *other)
{
    PyObject *result;

    if (!PyAnySet_Check(other))
        Py_RETURN_NOTIMPLEMENTED;
    PySetObject *so = _PySet_CAST(self);

    result = set_symmetric_difference_update(so, other);
    if (result == NULL)
        return NULL;
    Py_DECREF(result);
    return Py_NewRef(so);
}

/*[clinic input]
@critical_section so other
set.issubset
    so: setobject
    other: object
    /

Report whether another set contains this set.
[clinic start generated code]*/

static PyObject *
set_issubset_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=b2b59d5f314555ce input=f2a4fd0f2537758b]*/
{
    setentry *entry;
    Py_ssize_t pos = 0;
    int rv;

    if (!PyAnySet_Check(other)) {
        PyObject *tmp = set_intersection(so, other);
        if (tmp == NULL) {
            return NULL;
        }
        int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so));
        Py_DECREF(tmp);
        return PyBool_FromLong(result);
    }
    if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other))
        Py_RETURN_FALSE;

    while (set_next(so, &pos, &entry)) {
        PyObject *key = entry->key;
        Py_INCREF(key);
        rv = set_contains_entry((PySetObject *)other, key, entry->hash);
        Py_DECREF(key);
        if (rv < 0) {
            return NULL;
        }
        if (!rv) {
            Py_RETURN_FALSE;
        }
    }
    Py_RETURN_TRUE;
}

/*[clinic input]
@critical_section so other
set.issuperset
    so: setobject
    other: object
    /

Report whether this set contains another set.
[clinic start generated code]*/

static PyObject *
set_issuperset_impl(PySetObject *so, PyObject *other)
/*[clinic end generated code: output=ecf00ce552c09461 input=5f2e1f262e6e4ccc]*/
{
    if (PyAnySet_Check(other)) {
        return set_issubset((PySetObject *)other, (PyObject *)so);
    }

    PyObject *key, *it = PyObject_GetIter(other);
    if (it == NULL) {
        return NULL;
    }
    while ((key = PyIter_Next(it)) != NULL) {
        int rv = set_contains_key(so, key);
        Py_DECREF(key);
        if (rv < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (!rv) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        return NULL;
    }
    Py_RETURN_TRUE;
}

static PyObject *
set_richcompare(PyObject *self, PyObject *w, int op)
{
    PySetObject *v = _PySet_CAST(self);
    PyObject *r1;
    int r2;

    if(!PyAnySet_Check(w))
        Py_RETURN_NOTIMPLEMENTED;

    switch (op) {
    case Py_EQ:
        if (PySet_GET_SIZE(v) != PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        if (v->hash != -1  &&
            ((PySetObject *)w)->hash != -1 &&
            v->hash != ((PySetObject *)w)->hash)
            Py_RETURN_FALSE;
        return set_issubset(v, w);
    case Py_NE:
        r1 = set_richcompare((PyObject*)v, w, Py_EQ);
        if (r1 == NULL)
            return NULL;
        r2 = PyObject_IsTrue(r1);
        Py_DECREF(r1);
        if (r2 < 0)
            return NULL;
        return PyBool_FromLong(!r2);
    case Py_LE:
        return set_issubset(v, w);
    case Py_GE:
        return set_issuperset(v, w);
    case Py_LT:
        if (PySet_GET_SIZE(v) >= PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        return set_issubset(v, w);
    case Py_GT:
        if (PySet_GET_SIZE(v) <= PySet_GET_SIZE(w))
            Py_RETURN_FALSE;
        return set_issuperset(v, w);
    }
    Py_RETURN_NOTIMPLEMENTED;
}

/*[clinic input]
@critical_section
set.add
    so: setobject
    object as key: object
    /

Add an element to a set.

This has no effect if the element is already present.
[clinic start generated code]*/

static PyObject *
set_add_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=4cc4a937f1425c96 input=03baf62cb0e66514]*/
{
    if (set_add_key(so, key))
        return NULL;
    Py_RETURN_NONE;
}

static int
set_contains_lock_held(PySetObject *so, PyObject *key)
{
    int rv;

    rv = set_contains_key(so, key);
    if (rv < 0) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
            return -1;
        PyErr_Clear();
        Py_hash_t hash;
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
        rv = set_contains_entry(so, key, hash);
    }
    return rv;
}

int
_PySet_Contains(PySetObject *so, PyObject *key)
{
    int rv;
    Py_BEGIN_CRITICAL_SECTION(so);
    rv = set_contains_lock_held(so, key);
    Py_END_CRITICAL_SECTION();
    return rv;
}

static int
set_contains(PyObject *self, PyObject *key)
{
    PySetObject *so = _PySet_CAST(self);
    return _PySet_Contains(so, key);
}

/*[clinic input]
@critical_section
@coexist
set.__contains__
    so: setobject
    object as key: object
    /

x.__contains__(y) <==> y in x.
[clinic start generated code]*/

static PyObject *
set___contains___impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=b44863d034b3c70e input=4a7d568459617f24]*/
{
    long result;

    result = set_contains_lock_held(so, key);
    if (result < 0)
        return NULL;
    return PyBool_FromLong(result);
}

/*[clinic input]
@critical_section
set.remove
    so: setobject
    object as key: object
    /

Remove an element from a set; it must be a member.

If the element is not a member, raise a KeyError.
[clinic start generated code]*/

static PyObject *
set_remove_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=0b9134a2a2200363 input=893e1cb1df98227a]*/
{
    int rv;

    rv = set_discard_key(so, key);
    if (rv < 0) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
            return NULL;
        PyErr_Clear();
        Py_hash_t hash;
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
        rv = set_discard_entry(so, key, hash);
        if (rv < 0)
            return NULL;
    }

    if (rv == DISCARD_NOTFOUND) {
        _PyErr_SetKeyError(key);
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@critical_section
set.discard
    so: setobject
    object as key: object
    /

Remove an element from a set if it is a member.

Unlike set.remove(), the discard() method does not raise
an exception when an element is missing from the set.
[clinic start generated code]*/

static PyObject *
set_discard_impl(PySetObject *so, PyObject *key)
/*[clinic end generated code: output=eec3b687bf32759e input=861cb7fb69b4def0]*/
{
    int rv;

    rv = set_discard_key(so, key);
    if (rv < 0) {
        if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError))
            return NULL;
        PyErr_Clear();
        Py_hash_t hash;
        Py_BEGIN_CRITICAL_SECTION(key);
        hash = frozenset_hash_impl(key);
        Py_END_CRITICAL_SECTION();
        rv = set_discard_entry(so, key, hash);
        if (rv < 0)
            return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
@critical_section
set.__reduce__
    so: setobject

Return state information for pickling.
[clinic start generated code]*/

static PyObject *
set___reduce___impl(PySetObject *so)
/*[clinic end generated code: output=9af7d0e029df87ee input=59405a4249e82f71]*/
{
    PyObject *keys=NULL, *args=NULL, *result=NULL, *state=NULL;

    keys = PySequence_List((PyObject *)so);
    if (keys == NULL)
        goto done;
    args = PyTuple_Pack(1, keys);
    if (args == NULL)
        goto done;
    state = _PyObject_GetState((PyObject *)so);
    if (state == NULL)
        goto done;
    result = PyTuple_Pack(3, Py_TYPE(so), args, state);
done:
    Py_XDECREF(args);
    Py_XDECREF(keys);
    Py_XDECREF(state);
    return result;
}

/*[clinic input]
@critical_section
set.__sizeof__
    so: setobject

S.__sizeof__() -> size of S in memory, in bytes.
[clinic start generated code]*/

static PyObject *
set___sizeof___impl(PySetObject *so)
/*[clinic end generated code: output=4bfa3df7bd38ed88 input=09e1a09f168eaa23]*/
{
    size_t res = _PyObject_SIZE(Py_TYPE(so));
    if (so->table != so->smalltable) {
        res += ((size_t)so->mask + 1) * sizeof(setentry);
    }
    return PyLong_FromSize_t(res);
}

static int
set_init(PyObject *so, PyObject *args, PyObject *kwds)
{
    PySetObject *self = _PySet_CAST(so);
    PyObject *iterable = NULL;

    if (!_PyArg_NoKeywords("set", kwds))
        return -1;
    if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
        return -1;

    if (Py_REFCNT(self) == 1 && self->fill == 0) {
        self->hash = -1;
        if (iterable == NULL) {
            return 0;
        }
        return set_update_local(self, iterable);
    }
    Py_BEGIN_CRITICAL_SECTION(self);
    if (self->fill)
        set_clear_internal((PyObject*)self);
    self->hash = -1;
    Py_END_CRITICAL_SECTION();

    if (iterable == NULL)
        return 0;
    return set_update_internal(self, iterable);
}

static PyObject*
set_vectorcall(PyObject *type, PyObject * const*args,
               size_t nargsf, PyObject *kwnames)
{
    assert(PyType_Check(type));

    if (!_PyArg_NoKwnames("set", kwnames)) {
        return NULL;
    }

    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
    if (!_PyArg_CheckPositional("set", nargs, 0, 1)) {
        return NULL;
    }

    if (nargs) {
        return make_new_set(_PyType_CAST(type), args[0]);
    }

    return make_new_set(_PyType_CAST(type), NULL);
}

static PySequenceMethods set_as_sequence = {
    set_len,                            /* sq_length */
    0,                                  /* sq_concat */
    0,                                  /* sq_repeat */
    0,                                  /* sq_item */
    0,                                  /* sq_slice */
    0,                                  /* sq_ass_item */
    0,                                  /* sq_ass_slice */
    set_contains,                       /* sq_contains */
};

/* set object ********************************************************/

static PyMethodDef set_methods[] = {
    SET_ADD_METHODDEF
    SET_CLEAR_METHODDEF
    SET___CONTAINS___METHODDEF
    SET_COPY_METHODDEF
    SET_DISCARD_METHODDEF
    SET_DIFFERENCE_MULTI_METHODDEF
    SET_DIFFERENCE_UPDATE_METHODDEF
    SET_INTERSECTION_MULTI_METHODDEF
    SET_INTERSECTION_UPDATE_MULTI_METHODDEF
    SET_ISDISJOINT_METHODDEF
    SET_ISSUBSET_METHODDEF
    SET_ISSUPERSET_METHODDEF
    SET_POP_METHODDEF
    SET___REDUCE___METHODDEF
    SET_REMOVE_METHODDEF
    SET___SIZEOF___METHODDEF
    SET_SYMMETRIC_DIFFERENCE_METHODDEF
    SET_SYMMETRIC_DIFFERENCE_UPDATE_METHODDEF
    SET_UNION_METHODDEF
    SET_UPDATE_METHODDEF
    {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    {NULL,              NULL}   /* sentinel */
};

static PyNumberMethods set_as_number = {
    0,                                  /*nb_add*/
    set_sub,                            /*nb_subtract*/
    0,                                  /*nb_multiply*/
    0,                                  /*nb_remainder*/
    0,                                  /*nb_divmod*/
    0,                                  /*nb_power*/
    0,                                  /*nb_negative*/
    0,                                  /*nb_positive*/
    0,                                  /*nb_absolute*/
    0,                                  /*nb_bool*/
    0,                                  /*nb_invert*/
    0,                                  /*nb_lshift*/
    0,                                  /*nb_rshift*/
    set_and,                            /*nb_and*/
    set_xor,                            /*nb_xor*/
    set_or,                             /*nb_or*/
    0,                                  /*nb_int*/
    0,                                  /*nb_reserved*/
    0,                                  /*nb_float*/
    0,                                  /*nb_inplace_add*/
    set_isub,                           /*nb_inplace_subtract*/
    0,                                  /*nb_inplace_multiply*/
    0,                                  /*nb_inplace_remainder*/
    0,                                  /*nb_inplace_power*/
    0,                                  /*nb_inplace_lshift*/
    0,                                  /*nb_inplace_rshift*/
    set_iand,                           /*nb_inplace_and*/
    set_ixor,                           /*nb_inplace_xor*/
    set_ior,                            /*nb_inplace_or*/
};

PyDoc_STRVAR(set_doc,
"set(iterable=(), /)\n\
--\n\
\n\
Build an unordered collection of unique elements.");

PyTypeObject PySet_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "set",                              /* tp_name */
    sizeof(PySetObject),                /* tp_basicsize */
    0,                                  /* tp_itemsize */
    /* methods */
    set_dealloc,                        /* tp_dealloc */
    0,                                  /* tp_vectorcall_offset */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_as_async */
    set_repr,                           /* tp_repr */
    &set_as_number,                     /* tp_as_number */
    &set_as_sequence,                   /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    PyObject_HashNotImplemented,        /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    PyObject_GenericGetAttr,            /* tp_getattro */
    0,                                  /* tp_setattro */
    0,                                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE |
        _Py_TPFLAGS_MATCH_SELF,         /* tp_flags */
    set_doc,                            /* tp_doc */
    set_traverse,                       /* tp_traverse */
    set_clear_internal,                 /* tp_clear */
    set_richcompare,                    /* tp_richcompare */
    offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    set_iter,                           /* tp_iter */
    0,                                  /* tp_iternext */
    set_methods,                        /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    set_init,                           /* tp_init */
    PyType_GenericAlloc,                /* tp_alloc */
    set_new,                            /* tp_new */
    PyObject_GC_Del,                    /* tp_free */
    .tp_vectorcall = set_vectorcall,
    .tp_version_tag = _Py_TYPE_VERSION_SET,
};

/* frozenset object ********************************************************/


static PyMethodDef frozenset_methods[] = {
    SET___CONTAINS___METHODDEF
    FROZENSET_COPY_METHODDEF
    SET_DIFFERENCE_MULTI_METHODDEF
    SET_INTERSECTION_MULTI_METHODDEF
    SET_ISDISJOINT_METHODDEF
    SET_ISSUBSET_METHODDEF
    SET_ISSUPERSET_METHODDEF
    SET___REDUCE___METHODDEF
    SET___SIZEOF___METHODDEF
    SET_SYMMETRIC_DIFFERENCE_METHODDEF
    SET_UNION_METHODDEF
    {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
    {NULL,              NULL}   /* sentinel */
};

static PyNumberMethods frozenset_as_number = {
    0,                                  /*nb_add*/
    set_sub,                            /*nb_subtract*/
    0,                                  /*nb_multiply*/
    0,                                  /*nb_remainder*/
    0,                                  /*nb_divmod*/
    0,                                  /*nb_power*/
    0,                                  /*nb_negative*/
    0,                                  /*nb_positive*/
    0,                                  /*nb_absolute*/
    0,                                  /*nb_bool*/
    0,                                  /*nb_invert*/
    0,                                  /*nb_lshift*/
    0,                                  /*nb_rshift*/
    set_and,                            /*nb_and*/
    set_xor,                            /*nb_xor*/
    set_or,                             /*nb_or*/
};

PyDoc_STRVAR(frozenset_doc,
"frozenset(iterable=(), /)\n\
--\n\
\n\
Build an immutable unordered collection of unique elements.");

PyTypeObject PyFrozenSet_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "frozenset",                        /* tp_name */
    sizeof(PySetObject),                /* tp_basicsize */
    0,                                  /* tp_itemsize */
    /* methods */
    set_dealloc,                        /* tp_dealloc */
    0,                                  /* tp_vectorcall_offset */
    0,                                  /* tp_getattr */
    0,                                  /* tp_setattr */
    0,                                  /* tp_as_async */
    set_repr,                           /* tp_repr */
    &frozenset_as_number,               /* tp_as_number */
    &set_as_sequence,                   /* tp_as_sequence */
    0,                                  /* tp_as_mapping */
    frozenset_hash,                     /* tp_hash */
    0,                                  /* tp_call */
    0,                                  /* tp_str */
    PyObject_GenericGetAttr,            /* tp_getattro */
    0,                                  /* tp_setattro */
    0,                                  /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        Py_TPFLAGS_BASETYPE |
        _Py_TPFLAGS_MATCH_SELF,         /* tp_flags */
    frozenset_doc,                      /* tp_doc */
    set_traverse,                       /* tp_traverse */
    set_clear_internal,                 /* tp_clear */
    set_richcompare,                    /* tp_richcompare */
    offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */
    set_iter,                           /* tp_iter */
    0,                                  /* tp_iternext */
    frozenset_methods,                  /* tp_methods */
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    0,                                  /* tp_init */
    PyType_GenericAlloc,                /* tp_alloc */
    frozenset_new,                      /* tp_new */
    PyObject_GC_Del,                    /* tp_free */
    .tp_vectorcall = frozenset_vectorcall,
    .tp_version_tag = _Py_TYPE_VERSION_FROZEN_SET,
};


/***** C API functions *************************************************/

PyObject *
PySet_New(PyObject *iterable)
{
    return make_new_set(&PySet_Type, iterable);
}

PyObject *
PyFrozenSet_New(PyObject *iterable)
{
    return make_new_set(&PyFrozenSet_Type, iterable);
}

Py_ssize_t
PySet_Size(PyObject *anyset)
{
    if (!PyAnySet_Check(anyset)) {
        PyErr_BadInternalCall();
        return -1;
    }
    return set_len(anyset);
}

int
PySet_Clear(PyObject *set)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    (void)set_clear((PySetObject *)set, NULL);
    return 0;
}

void
_PySet_ClearInternal(PySetObject *so)
{
    (void)set_clear_internal((PyObject*)so);
}

int
PySet_Contains(PyObject *anyset, PyObject *key)
{
    if (!PyAnySet_Check(anyset)) {
        PyErr_BadInternalCall();
        return -1;
    }

    int rv;
    Py_BEGIN_CRITICAL_SECTION(anyset);
    rv = set_contains_key((PySetObject *)anyset, key);
    Py_END_CRITICAL_SECTION();
    return rv;
}

int
PySet_Discard(PyObject *set, PyObject *key)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }

    int rv;
    Py_BEGIN_CRITICAL_SECTION(set);
    rv = set_discard_key((PySetObject *)set, key);
    Py_END_CRITICAL_SECTION();
    return rv;
}

int
PySet_Add(PyObject *anyset, PyObject *key)
{
    if (!PySet_Check(anyset) &&
        (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) {
        PyErr_BadInternalCall();
        return -1;
    }

    int rv;
    Py_BEGIN_CRITICAL_SECTION(anyset);
    rv = set_add_key((PySetObject *)anyset, key);
    Py_END_CRITICAL_SECTION();
    return rv;
}

int
_PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
    setentry *entry;

    if (!PyAnySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    if (set_next((PySetObject *)set, pos, &entry) == 0)
        return 0;
    *key = entry->key;
    *hash = entry->hash;
    return 1;
}

int
_PySet_NextEntryRef(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash)
{
    setentry *entry;

    if (!PyAnySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(set);
    if (set_next((PySetObject *)set, pos, &entry) == 0)
        return 0;
    *key = Py_NewRef(entry->key);
    *hash = entry->hash;
    return 1;
}

PyObject *
PySet_Pop(PyObject *set)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return NULL;
    }
    return set_pop((PySetObject *)set, NULL);
}

int
_PySet_Update(PyObject *set, PyObject *iterable)
{
    if (!PySet_Check(set)) {
        PyErr_BadInternalCall();
        return -1;
    }
    return set_update_internal((PySetObject *)set, iterable);
}

/* Exported for the gdb plugin's benefit. */
PyObject *_PySet_Dummy = dummy;

/***** Dummy Struct  *************************************************/

static PyObject *
dummy_repr(PyObject *op)
{
    return PyUnicode_FromString("<dummy key>");
}

static void _Py_NO_RETURN
dummy_dealloc(PyObject* ignore)
{
    Py_FatalError("deallocating <dummy key>");
}

static PyTypeObject _PySetDummy_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "<dummy key> type",
    0,
    0,
    dummy_dealloc,      /*tp_dealloc*/ /*never called*/
    0,                  /*tp_vectorcall_offset*/
    0,                  /*tp_getattr*/
    0,                  /*tp_setattr*/
    0,                  /*tp_as_async*/
    dummy_repr,         /*tp_repr*/
    0,                  /*tp_as_number*/
    0,                  /*tp_as_sequence*/
    0,                  /*tp_as_mapping*/
    0,                  /*tp_hash */
    0,                  /*tp_call */
    0,                  /*tp_str */
    0,                  /*tp_getattro */
    0,                  /*tp_setattro */
    0,                  /*tp_as_buffer */
    Py_TPFLAGS_DEFAULT, /*tp_flags */
};

static PyObject _dummy_struct = _PyObject_HEAD_INIT(&_PySetDummy_Type);
