/* Ordered Dictionary object implementation.

This implementation is necessarily explicitly equivalent to the pure Python
OrderedDict class in Lib/collections/__init__.py.  The strategy there
involves using a doubly-linked-list to capture the order.  We keep to that
strategy, using a lower-level linked-list.

About the Linked-List
=====================

For the linked list we use a basic doubly-linked-list.  Using a circularly-
linked-list does have some benefits, but they don't apply so much here
since OrderedDict is focused on the ends of the list (for the most part).
Furthermore, there are some features of generic linked-lists that we simply
don't need for OrderedDict.  Thus a simple custom implementation meets our
needs.  Alternatives to our simple approach include the QCIRCLE_*
macros from BSD's queue.h, and the linux's list.h.

Getting O(1) Node Lookup
------------------------

One invariant of Python's OrderedDict is that it preserves time complexity
of dict's methods, particularly the O(1) operations.  Simply adding a
linked-list on top of dict is not sufficient here; operations for nodes in
the middle of the linked-list implicitly require finding the node first.
With a simple linked-list like we're using, that is an O(n) operation.
Consequently, methods like __delitem__() would change from O(1) to O(n),
which is unacceptable.

In order to preserve O(1) performance for node removal (finding nodes), we
must do better than just looping through the linked-list.  Here are options
we've considered:

1. use a second dict to map keys to nodes (a la the pure Python version).
2. keep a simple hash table mirroring the order of dict's, mapping each key
   to the corresponding node in the linked-list.
3. use a version of shared keys (split dict) that allows non-unicode keys.
4. have the value stored for each key be a (value, node) pair, and adjust
   __getitem__(), get(), etc. accordingly.

The approach with the least performance impact (time and space) is #2,
mirroring the key order of dict's dk_entries with an array of node pointers.
While _Py_dict_lookup() does not give us the index into the array,
we make use of pointer arithmetic to get that index.  An alternative would
be to refactor _Py_dict_lookup() to provide the index, explicitly exposing
the implementation detail.  We could even just use a custom lookup function
for OrderedDict that facilitates our need.  However, both approaches are
significantly more complicated than just using pointer arithmetic.

The catch with mirroring the hash table ordering is that we have to keep
the ordering in sync through any dict resizes.  However, that order only
matters during node lookup.  We can simply defer any potential resizing
until we need to do a lookup.

Linked-List Nodes
-----------------

The current implementation stores a pointer to the associated key only.
One alternative would be to store a pointer to the PyDictKeyEntry instead.
This would save one pointer de-reference per item, which is nice during
calls to values() and items().  However, it adds unnecessary overhead
otherwise, so we stick with just the key.

Linked-List API
---------------

As noted, the linked-list implemented here does not have all the bells and
whistles.  However, we recognize that the implementation may need to
change to accommodate performance improvements or extra functionality.  To
that end, we use a simple API to interact with the linked-list.  Here's a
summary of the methods/macros:

Node info:

* _odictnode_KEY(node)
* _odictnode_VALUE(od, node)
* _odictnode_PREV(node)
* _odictnode_NEXT(node)

Linked-List info:

* _odict_FIRST(od)
* _odict_LAST(od)
* _odict_EMPTY(od)
* _odict_FOREACH(od, node) - used in place of `for (node=...)`

For adding nodes:

* _odict_add_head(od, node)
* _odict_add_tail(od, node)
* _odict_add_new_node(od, key, hash)

For removing nodes:

* _odict_clear_node(od, node, key, hash)
* _odict_clear_nodes(od, clear_each)

Others:

* _odict_find_node_hash(od, key, hash)
* _odict_find_node(od, key)
* _odict_keys_equal(od1, od2)

And here's a look at how the linked-list relates to the OrderedDict API:

============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
method       key val prev next mem  1st last empty iter find add rmv  clr keq
============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===
__del__                                      ~                        X
__delitem__                    free                     ~        node
__eq__       ~                                                            X
__iter__     X            X
__new__                             X   X
__reduce__   X   ~                                 X
__repr__     X   X                                 X
__reversed__ X       X
__setitem__                                                  key
__sizeof__                     size          X
clear                          ~             ~                        X
copy         X   X                                 X
items        X   X        X
keys         X            X
move_to_end  X                      X   X               ~    h/t key
pop                            free                              key
popitem      X   X             free X   X                        node
setdefault       ~                                      ?    ~
values           X        X
============ === === ==== ==== ==== === ==== ===== ==== ==== === ==== === ===

__delitem__ is the only method that directly relies on finding an arbitrary
node in the linked-list.  Everything else is iteration or relates to the
ends of the linked-list.

Situation that Endangers Consistency
------------------------------------
Using a raw linked-list for OrderedDict exposes a key situation that can
cause problems.  If a node is stored in a variable, there is a chance that
the node may have been deallocated before the variable gets used, thus
potentially leading to a segmentation fault.  A key place where this shows
up is during iteration through the linked list (via _odict_FOREACH or
otherwise).

A number of solutions are available to resolve this situation:

* defer looking up the node until as late as possible and certainly after
  any code that could possibly result in a deletion;
* if the node is needed both before and after a point where the node might
  be removed, do a check before using the node at the "after" location to
  see if the node is still valid;
* like the last one, but simply pull the node again to ensure it's right;
* keep the key in the variable instead of the node and then look up the
  node using the key at the point where the node is needed (this is what
  we do for the iterators).

Another related problem, preserving consistent ordering during iteration,
is described below.  That one is not exclusive to using linked-lists.


Challenges from Subclassing dict
================================

OrderedDict subclasses dict, which is an unusual relationship between two
builtin types (other than the base object type).  Doing so results in
some complication and deserves further explanation.  There are two things
to consider here.  First, in what circumstances or with what adjustments
can OrderedDict be used as a drop-in replacement for dict (at the C level)?
Second, how can the OrderedDict implementation leverage the dict
implementation effectively without introducing unnecessary coupling or
inefficiencies?

This second point is reflected here and in the implementation, so the
further focus is on the first point.  It is worth noting that for
overridden methods, the dict implementation is deferred to as much as
possible.  Furthermore, coupling is limited to as little as is reasonable.

Concrete API Compatibility
--------------------------

Use of the concrete C-API for dict (PyDict_*) with OrderedDict is
problematic.  (See http://bugs.python.org/issue10977.)  The concrete API
has a number of hard-coded assumptions tied to the dict implementation.
This is, in part, due to performance reasons, which is understandable
given the part dict plays in Python.

Any attempt to replace dict with OrderedDict for any role in the
interpreter (e.g. **kwds) faces a challenge.  Such any effort must
recognize that the instances in affected locations currently interact with
the concrete API.

Here are some ways to address this challenge:

1. Change the relevant usage of the concrete API in CPython and add
   PyDict_CheckExact() calls to each of the concrete API functions.
2. Adjust the relevant concrete API functions to explicitly accommodate
   OrderedDict.
3. As with #1, add the checks, but improve the abstract API with smart fast
   paths for dict and OrderedDict, and refactor CPython to use the abstract
   API.  Improvements to the abstract API would be valuable regardless.

Adding the checks to the concrete API would help make any interpreter
switch to OrderedDict less painful for extension modules.  However, this
won't work.  The equivalent C API call to `dict.__setitem__(obj, k, v)`
is 'PyDict_SetItem(obj, k, v)`.  This illustrates how subclasses in C call
the base class's methods, since there is no equivalent of super() in the
C API.  Calling into Python for parent class API would work, but some
extension modules already rely on this feature of the concrete API.

For reference, here is a breakdown of some of the dict concrete API:

========================== ============= =======================
concrete API               uses          abstract API
========================== ============= =======================
PyDict_Check                             PyMapping_Check
(PyDict_CheckExact)                      -
(PyDict_New)                             -
(PyDictProxy_New)                        -
PyDict_Clear                             -
PyDict_Contains                          PySequence_Contains
PyDict_Copy                              -
PyDict_SetItem                           PyObject_SetItem
PyDict_SetItemString                     PyMapping_SetItemString
PyDict_DelItem                           PyMapping_DelItem
PyDict_DelItemString                     PyMapping_DelItemString
PyDict_GetItem                           -
PyDict_GetItemWithError                  PyObject_GetItem
_PyDict_GetItemIdWithError               -
PyDict_GetItemString                     PyMapping_GetItemString
PyDict_Items                             PyMapping_Items
PyDict_Keys                              PyMapping_Keys
PyDict_Values                            PyMapping_Values
PyDict_Size                              PyMapping_Size
                                         PyMapping_Length
PyDict_Next                              PyIter_Next
_PyDict_Next                             -
PyDict_Merge                             -
PyDict_Update                            -
PyDict_MergeFromSeq2                     -
PyDict_ClearFreeList                     -
-                                        PyMapping_HasKeyString
-                                        PyMapping_HasKey
========================== ============= =======================


The dict Interface Relative to OrderedDict
==========================================

Since OrderedDict subclasses dict, understanding the various methods and
attributes of dict is important for implementing OrderedDict.

Relevant Type Slots
-------------------

================= ================ =================== ================
slot              attribute        object              dict
================= ================ =================== ================
tp_dealloc        -                object_dealloc      dict_dealloc
tp_repr           __repr__         object_repr         dict_repr
sq_contains       __contains__     -                   dict_contains
mp_length         __len__          -                   dict_length
mp_subscript      __getitem__      -                   dict_subscript
mp_ass_subscript  __setitem__      -                   dict_ass_sub
                  __delitem__
tp_hash           __hash__         _Py_HashPointer     ..._HashNotImpl
tp_str            __str__          object_str          -
tp_getattro       __getattribute__ ..._GenericGetAttr  (repeated)
                  __getattr__
tp_setattro       __setattr__      ..._GenericSetAttr  (disabled)
tp_doc            __doc__          (literal)           dictionary_doc
tp_traverse       -                -                   dict_traverse
tp_clear          -                -                   dict_tp_clear
tp_richcompare    __eq__           object_richcompare  dict_richcompare
                  __ne__
tp_weaklistoffset (__weakref__)    -                   -
tp_iter           __iter__         -                   dict_iter
tp_dictoffset     (__dict__)       -                   -
tp_init           __init__         object_init         dict_init
tp_alloc          -                PyType_GenericAlloc (repeated)
tp_new            __new__          object_new          dict_new
tp_free           -                PyObject_Del        PyObject_GC_Del
================= ================ =================== ================

Relevant Methods
----------------

================ =================== ===============
method           object              dict
================ =================== ===============
__reduce__       object_reduce       -
__sizeof__       object_sizeof       dict_sizeof
clear            -                   dict_clear
copy             -                   dict_copy
fromkeys         -                   dict_fromkeys
get              -                   dict_get
items            -                   dictitems_new
keys             -                   dictkeys_new
pop              -                   dict_pop
popitem          -                   dict_popitem
setdefault       -                   dict_setdefault
update           -                   dict_update
values           -                   dictvalues_new
================ =================== ===============


Pure Python OrderedDict
=======================

As already noted, compatibility with the pure Python OrderedDict
implementation is a key goal of this C implementation.  To further that
goal, here's a summary of how OrderedDict-specific methods are implemented
in collections/__init__.py.  Also provided is an indication of which
methods directly mutate or iterate the object, as well as any relationship
with the underlying linked-list.

============= ============== == ================ === === ====
method        impl used      ll uses             inq mut iter
============= ============== == ================ === === ====
__contains__  dict           -  -                X
__delitem__   OrderedDict    Y  dict.__delitem__     X
__eq__        OrderedDict    N  OrderedDict      ~
                                dict.__eq__
                                __iter__
__getitem__   dict           -  -                X
__iter__      OrderedDict    Y  -                        X
__init__      OrderedDict    N  update
__len__       dict           -  -                X
__ne__        MutableMapping -  __eq__           ~
__reduce__    OrderedDict    N  OrderedDict      ~
                                __iter__
                                __getitem__
__repr__      OrderedDict    N  __class__        ~
                                items
__reversed__  OrderedDict    Y  -                        X
__setitem__   OrderedDict    Y  __contains__         X
                                dict.__setitem__
__sizeof__    OrderedDict    Y  __len__          ~
                                __dict__
clear         OrderedDict    Y  dict.clear           X
copy          OrderedDict    N  __class__
                                __init__
fromkeys      OrderedDict    N  __setitem__
get           dict           -  -                ~
items         MutableMapping -  ItemsView                X
keys          MutableMapping -  KeysView                 X
move_to_end   OrderedDict    Y  -                    X
pop           OrderedDict    N  __contains__         X
                                __getitem__
                                __delitem__
popitem       OrderedDict    Y  dict.pop             X
setdefault    OrderedDict    N  __contains__         ~
                                __getitem__
                                __setitem__
update        MutableMapping -  __setitem__          ~
values        MutableMapping -  ValuesView               X
============= ============== == ================ === === ====

__reversed__ and move_to_end are both exclusive to OrderedDict.


C OrderedDict Implementation
============================

================= ================
slot              impl
================= ================
tp_dealloc        odict_dealloc
tp_repr           odict_repr
mp_ass_subscript  odict_ass_sub
tp_doc            odict_doc
tp_traverse       odict_traverse
tp_clear          odict_tp_clear
tp_richcompare    odict_richcompare
tp_weaklistoffset (offset)
tp_iter           odict_iter
tp_dictoffset     (offset)
tp_init           odict_init
tp_alloc          (repeated)
================= ================

================= ================
method            impl
================= ================
__reduce__        odict_reduce
__sizeof__        odict_sizeof
clear             odict_clear
copy              odict_copy
fromkeys          odict_fromkeys
items             odictitems_new
keys              odictkeys_new
pop               odict_pop
popitem           odict_popitem
setdefault        odict_setdefault
update            odict_update
values            odictvalues_new
================= ================

Inherited unchanged from object/dict:

================ ==========================
method           type field
================ ==========================
-                tp_free
__contains__     tp_as_sequence.sq_contains
__getattr__      tp_getattro
__getattribute__ tp_getattro
__getitem__      tp_as_mapping.mp_subscript
__hash__         tp_hash
__len__          tp_as_mapping.mp_length
__setattr__      tp_setattro
__str__          tp_str
get              -
================ ==========================


Other Challenges
================

Preserving Ordering During Iteration
------------------------------------
During iteration through an OrderedDict, it is possible that items could
get added, removed, or reordered.  For a linked-list implementation, as
with some other implementations, that situation may lead to undefined
behavior.  The documentation for dict mentions this in the `iter()` section
of http://docs.python.org/3.4/library/stdtypes.html#dictionary-view-objects.
In this implementation we follow dict's lead (as does the pure Python
implementation) for __iter__(), keys(), values(), and items().

For internal iteration (using _odict_FOREACH or not), there is still the
risk that not all nodes that we expect to be seen in the loop actually get
seen.  Thus, we are careful in each of those places to ensure that they
are.  This comes, of course, at a small price at each location.  The
solutions are much the same as those detailed in the `Situation that
Endangers Consistency` section above.


Potential Optimizations
=======================

* Allocate the nodes as a block via od_fast_nodes instead of individually.
  - Set node->key to NULL to indicate the node is not-in-use.
  - Add _odict_EXISTS()?
  - How to maintain consistency across resizes?  Existing node pointers
    would be invalidated after a resize, which is particularly problematic
    for the iterators.
* Use a more stream-lined implementation of update() and, likely indirectly,
  __init__().

*/

/* TODO

sooner:
- reentrancy (make sure everything is at a thread-safe state when calling
  into Python).  I've already checked this multiple times, but want to
  make one more pass.
- add unit tests for reentrancy?

later:
- make the dict views support the full set API (the pure Python impl does)
- implement a fuller MutableMapping API in C?
- move the MutableMapping implementation to abstract.c?
- optimize mutablemapping_update
- use PyObject_Malloc (small object allocator) for odict nodes?
- support subclasses better (e.g. in odict_richcompare)

*/

#include "Python.h"
#include "pycore_call.h"             // _PyObject_CallNoArgs()
#include "pycore_ceval.h"            // _PyEval_GetBuiltin()
#include "pycore_critical_section.h" //_Py_BEGIN_CRITICAL_SECTION
#include "pycore_dict.h"             // _Py_dict_lookup()
#include "pycore_object.h"           // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h"         // _PyErr_ChainExceptions1()
#include <stddef.h>                  // offsetof()

#include "clinic/odictobject.c.h"

/*[clinic input]
class OrderedDict "PyODictObject *" "&PyODict_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ca0641cf6143d4af]*/


typedef struct _odictnode _ODictNode;

/* PyODictObject */
struct _odictobject {
    PyDictObject od_dict;        /* the underlying dict */
    _ODictNode *od_first;        /* first node in the linked list, if any */
    _ODictNode *od_last;         /* last node in the linked list, if any */
    /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed
     * by _odict_resize().
     * Note that we rely on implementation details of dict for both. */
    _ODictNode **od_fast_nodes;  /* hash table that mirrors the dict table */
    Py_ssize_t od_fast_nodes_size;
    void *od_resize_sentinel;    /* changes if odict should be resized */

    size_t od_state;             /* incremented whenever the LL changes */
    PyObject *od_inst_dict;      /* OrderedDict().__dict__ */
    PyObject *od_weakreflist;    /* holds weakrefs to the odict */
};


/* ----------------------------------------------
 * odict keys (a simple doubly-linked list)
 */

struct _odictnode {
    PyObject *key;
    Py_hash_t hash;
    _ODictNode *next;
    _ODictNode *prev;
};

#define _odictnode_KEY(node) \
    (node->key)
#define _odictnode_HASH(node) \
    (node->hash)
/* borrowed reference */
#define _odictnode_VALUE(node, od) \
    PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
#define _odictnode_PREV(node) (node->prev)
#define _odictnode_NEXT(node) (node->next)

#define _odict_FIRST(od) (((PyODictObject *)od)->od_first)
#define _odict_LAST(od) (((PyODictObject *)od)->od_last)
#define _odict_EMPTY(od) (_odict_FIRST(od) == NULL)
#define _odict_FOREACH(od, node) \
    for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))

/* Return the index into the hash table, regardless of a valid node. */
static Py_ssize_t
_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash)
{
    PyObject *value = NULL;
    PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys;
    Py_ssize_t ix;
#ifdef Py_GIL_DISABLED
    ix = _Py_dict_lookup_threadsafe((PyDictObject *)od, key, hash, &value);
    Py_XDECREF(value);
#else
    ix = _Py_dict_lookup((PyDictObject *)od, key, hash, &value);
#endif
    if (ix == DKIX_EMPTY) {
        return keys->dk_nentries;  /* index of new entry */
    }
    if (ix < 0)
        return -1;
    /* We use pointer arithmetic to get the entry's index into the table. */
    return ix;
}

#define ONE ((Py_ssize_t)1)

/* Replace od->od_fast_nodes with a new table matching the size of dict's. */
static int
_odict_resize(PyODictObject *od)
{
    Py_ssize_t size, i;
    _ODictNode **fast_nodes, *node;

    /* Initialize a new "fast nodes" table. */
    size = ONE << (((PyDictObject *)od)->ma_keys->dk_log2_size);
    fast_nodes = PyMem_NEW(_ODictNode *, size);
    if (fast_nodes == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    for (i = 0; i < size; i++)
        fast_nodes[i] = NULL;

    /* Copy the current nodes into the table. */
    _odict_FOREACH(od, node) {
        i = _odict_get_index_raw(od, _odictnode_KEY(node),
                                 _odictnode_HASH(node));
        if (i < 0) {
            PyMem_Free(fast_nodes);
            return -1;
        }
        fast_nodes[i] = node;
    }

    /* Replace the old fast nodes table. */
    PyMem_Free(od->od_fast_nodes);
    od->od_fast_nodes = fast_nodes;
    od->od_fast_nodes_size = size;
    od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys;
    return 0;
}

/* Return the index into the hash table, regardless of a valid node. */
static Py_ssize_t
_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash)
{
    PyDictKeysObject *keys;

    assert(key != NULL);
    keys = ((PyDictObject *)od)->ma_keys;

    /* Ensure od_fast_nodes and dk_entries are in sync. */
    if (od->od_resize_sentinel != keys ||
        od->od_fast_nodes_size != (ONE << (keys->dk_log2_size))) {
        int resize_res = _odict_resize(od);
        if (resize_res < 0)
            return -1;
    }

    return _odict_get_index_raw(od, key, hash);
}

/* Returns NULL if there was some error or the key was not found. */
static _ODictNode *
_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash)
{
    Py_ssize_t index;

    if (_odict_EMPTY(od))
        return NULL;
    index = _odict_get_index(od, key, hash);
    if (index < 0)
        return NULL;
    assert(od->od_fast_nodes != NULL);
    return od->od_fast_nodes[index];
}

static _ODictNode *
_odict_find_node(PyODictObject *od, PyObject *key)
{
    Py_ssize_t index;
    Py_hash_t hash;

    if (_odict_EMPTY(od))
        return NULL;
    hash = PyObject_Hash(key);
    if (hash == -1)
        return NULL;
    index = _odict_get_index(od, key, hash);
    if (index < 0)
        return NULL;
    assert(od->od_fast_nodes != NULL);
    return od->od_fast_nodes[index];
}

static void
_odict_add_head(PyODictObject *od, _ODictNode *node)
{
    _odictnode_PREV(node) = NULL;
    _odictnode_NEXT(node) = _odict_FIRST(od);
    if (_odict_FIRST(od) == NULL)
        _odict_LAST(od) = node;
    else
        _odictnode_PREV(_odict_FIRST(od)) = node;
    _odict_FIRST(od) = node;
    od->od_state++;
}

static void
_odict_add_tail(PyODictObject *od, _ODictNode *node)
{
    _odictnode_PREV(node) = _odict_LAST(od);
    _odictnode_NEXT(node) = NULL;
    if (_odict_LAST(od) == NULL)
        _odict_FIRST(od) = node;
    else
        _odictnode_NEXT(_odict_LAST(od)) = node;
    _odict_LAST(od) = node;
    od->od_state++;
}

/* adds the node to the end of the list */
static int
_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash)
{
    Py_ssize_t i;
    _ODictNode *node;

    Py_INCREF(key);
    i = _odict_get_index(od, key, hash);
    if (i < 0) {
        if (!PyErr_Occurred())
            PyErr_SetObject(PyExc_KeyError, key);
        Py_DECREF(key);
        return -1;
    }
    assert(od->od_fast_nodes != NULL);
    if (od->od_fast_nodes[i] != NULL) {
        /* We already have a node for the key so there's no need to add one. */
        Py_DECREF(key);
        return 0;
    }

    /* must not be added yet */
    node = (_ODictNode *)PyMem_Malloc(sizeof(_ODictNode));
    if (node == NULL) {
        Py_DECREF(key);
        PyErr_NoMemory();
        return -1;
    }

    _odictnode_KEY(node) = key;
    _odictnode_HASH(node) = hash;
    _odict_add_tail(od, node);
    od->od_fast_nodes[i] = node;
    return 0;
}

/* Putting the decref after the free causes problems. */
#define _odictnode_DEALLOC(node) \
    do { \
        Py_DECREF(_odictnode_KEY(node)); \
        PyMem_Free((void *)node); \
    } while (0)

/* Repeated calls on the same node are no-ops. */
static void
_odict_remove_node(PyODictObject *od, _ODictNode *node)
{
    if (_odict_FIRST(od) == node)
        _odict_FIRST(od) = _odictnode_NEXT(node);
    else if (_odictnode_PREV(node) != NULL)
        _odictnode_NEXT(_odictnode_PREV(node)) = _odictnode_NEXT(node);

    if (_odict_LAST(od) == node)
        _odict_LAST(od) = _odictnode_PREV(node);
    else if (_odictnode_NEXT(node) != NULL)
        _odictnode_PREV(_odictnode_NEXT(node)) = _odictnode_PREV(node);

    _odictnode_PREV(node) = NULL;
    _odictnode_NEXT(node) = NULL;
    od->od_state++;
}

/* If someone calls PyDict_DelItem() directly on an OrderedDict, we'll
   get all sorts of problems here.  In PyODict_DelItem we make sure to
   call _odict_clear_node first.

   This matters in the case of colliding keys.  Suppose we add 3 keys:
   [A, B, C], where the hash of C collides with A and the next possible
   index in the hash table is occupied by B.  If we remove B then for C
   the dict's looknode func will give us the old index of B instead of
   the index we got before deleting B.  However, the node for C in
   od_fast_nodes is still at the old dict index of C.  Thus to be sure
   things don't get out of sync, we clear the node in od_fast_nodes
   *before* calling PyDict_DelItem.

   The same must be done for any other OrderedDict operations where
   we modify od_fast_nodes.
*/
static int
_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key,
                  Py_hash_t hash)
{
    Py_ssize_t i;

    assert(key != NULL);
    if (_odict_EMPTY(od)) {
        /* Let later code decide if this is a KeyError. */
        return 0;
    }

    i = _odict_get_index(od, key, hash);
    if (i < 0)
        return PyErr_Occurred() ? -1 : 0;

    assert(od->od_fast_nodes != NULL);
    if (node == NULL)
        node = od->od_fast_nodes[i];
    assert(node == od->od_fast_nodes[i]);
    if (node == NULL) {
        /* Let later code decide if this is a KeyError. */
        return 0;
    }

    // Now clear the node.
    od->od_fast_nodes[i] = NULL;
    _odict_remove_node(od, node);
    _odictnode_DEALLOC(node);
    return 0;
}

static void
_odict_clear_nodes(PyODictObject *od)
{
    _ODictNode *node, *next;

    PyMem_Free(od->od_fast_nodes);
    od->od_fast_nodes = NULL;
    od->od_fast_nodes_size = 0;
    od->od_resize_sentinel = NULL;

    node = _odict_FIRST(od);
    _odict_FIRST(od) = NULL;
    _odict_LAST(od) = NULL;
    while (node != NULL) {
        next = _odictnode_NEXT(node);
        _odictnode_DEALLOC(node);
        node = next;
    }
}

/* There isn't any memory management of nodes past this point. */
#undef _odictnode_DEALLOC

static int
_odict_keys_equal(PyODictObject *a, PyODictObject *b)
{
    _ODictNode *node_a, *node_b;

    node_a = _odict_FIRST(a);
    node_b = _odict_FIRST(b);
    while (1) {
        if (node_a == NULL && node_b == NULL)
            /* success: hit the end of each at the same time */
            return 1;
        else if (node_a == NULL || node_b == NULL)
            /* unequal length */
            return 0;
        else {
            int res = PyObject_RichCompareBool(
                                            (PyObject *)_odictnode_KEY(node_a),
                                            (PyObject *)_odictnode_KEY(node_b),
                                            Py_EQ);
            if (res < 0)
                return res;
            else if (res == 0)
                return 0;

            /* otherwise it must match, so move on to the next one */
            node_a = _odictnode_NEXT(node_a);
            node_b = _odictnode_NEXT(node_b);
        }
    }
}


/* ----------------------------------------------
 * OrderedDict mapping methods
 */

/* mp_ass_subscript: __setitem__() and __delitem__() */

static int
odict_mp_ass_sub(PyODictObject *od, PyObject *v, PyObject *w)
{
    if (w == NULL)
        return PyODict_DelItem((PyObject *)od, v);
    else
        return PyODict_SetItem((PyObject *)od, v, w);
}

/* tp_as_mapping */

static PyMappingMethods odict_as_mapping = {
    0,                                  /*mp_length*/
    0,                                  /*mp_subscript*/
    (objobjargproc)odict_mp_ass_sub,    /*mp_ass_subscript*/
};


/* ----------------------------------------------
 * OrderedDict number methods
 */

static int mutablemapping_update_arg(PyObject*, PyObject*);

static PyObject *
odict_or(PyObject *left, PyObject *right)
{
    PyTypeObject *type;
    PyObject *other;
    if (PyODict_Check(left)) {
        type = Py_TYPE(left);
        other = right;
    }
    else {
        type = Py_TYPE(right);
        other = left;
    }
    if (!PyDict_Check(other)) {
        Py_RETURN_NOTIMPLEMENTED;
    }
    PyObject *new = PyObject_CallOneArg((PyObject*)type, left);
    if (!new) {
        return NULL;
    }
    if (mutablemapping_update_arg(new, right) < 0) {
        Py_DECREF(new);
        return NULL;
    }
    return new;
}

static PyObject *
odict_inplace_or(PyObject *self, PyObject *other)
{
    if (mutablemapping_update_arg(self, other) < 0) {
        return NULL;
    }
    return Py_NewRef(self);
}

/* tp_as_number */

static PyNumberMethods odict_as_number = {
    .nb_or = odict_or,
    .nb_inplace_or = odict_inplace_or,
};


/* ----------------------------------------------
 * OrderedDict methods
 */

/* fromkeys() */

/*[clinic input]
@classmethod
OrderedDict.fromkeys

    iterable as seq: object
    value: object = None

Create a new ordered dictionary with keys from iterable and values set to value.
[clinic start generated code]*/

static PyObject *
OrderedDict_fromkeys_impl(PyTypeObject *type, PyObject *seq, PyObject *value)
/*[clinic end generated code: output=c10390d452d78d6d input=1a0476c229c597b3]*/
{
    return _PyDict_FromKeys((PyObject *)type, seq, value);
}

/* __sizeof__() */

/* OrderedDict.__sizeof__() does not have a docstring. */
PyDoc_STRVAR(odict_sizeof__doc__, "");

static PyObject *
odict_sizeof(PyODictObject *od, PyObject *Py_UNUSED(ignored))
{
    Py_ssize_t res = _PyDict_SizeOf((PyDictObject *)od);
    res += sizeof(_ODictNode *) * od->od_fast_nodes_size;  /* od_fast_nodes */
    if (!_odict_EMPTY(od)) {
        res += sizeof(_ODictNode) * PyODict_SIZE(od);  /* linked-list */
    }
    return PyLong_FromSsize_t(res);
}

/* __reduce__() */

PyDoc_STRVAR(odict_reduce__doc__, "Return state information for pickling");

static PyObject *
odict_reduce(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
{
    PyObject *state, *result = NULL;
    PyObject *items_iter, *items, *args = NULL;

    /* capture any instance state */
    state = _PyObject_GetState((PyObject *)od);
    if (state == NULL)
        goto Done;

    /* build the result */
    args = PyTuple_New(0);
    if (args == NULL)
        goto Done;

    items = PyObject_CallMethodNoArgs((PyObject *)od, &_Py_ID(items));
    if (items == NULL)
        goto Done;

    items_iter = PyObject_GetIter(items);
    Py_DECREF(items);
    if (items_iter == NULL)
        goto Done;

    result = PyTuple_Pack(5, Py_TYPE(od), args, state, Py_None, items_iter);
    Py_DECREF(items_iter);

Done:
    Py_XDECREF(state);
    Py_XDECREF(args);

    return result;
}

/* setdefault(): Skips __missing__() calls. */


/*[clinic input]
OrderedDict.setdefault

    key: object
    default: object = None

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.
[clinic start generated code]*/

static PyObject *
OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key,
                            PyObject *default_value)
/*[clinic end generated code: output=97537cb7c28464b6 input=38e098381c1efbc6]*/
{
    PyObject *result = NULL;

    if (PyODict_CheckExact(self)) {
        result = PyODict_GetItemWithError(self, key);  /* borrowed */
        if (result == NULL) {
            if (PyErr_Occurred())
                return NULL;
            assert(_odict_find_node(self, key) == NULL);
            if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) {
                result = Py_NewRef(default_value);
            }
        }
        else {
            Py_INCREF(result);
        }
    }
    else {
        int exists = PySequence_Contains((PyObject *)self, key);
        if (exists < 0) {
            return NULL;
        }
        else if (exists) {
            result = PyObject_GetItem((PyObject *)self, key);
        }
        else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) {
            result = Py_NewRef(default_value);
        }
    }

    return result;
}

/* pop() */

static PyObject *
_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj,
                   Py_hash_t hash)
{
    PyObject *value = NULL;

    Py_BEGIN_CRITICAL_SECTION(od);

    _ODictNode *node = _odict_find_node_hash((PyODictObject *)od, key, hash);
    if (node != NULL) {
        /* Pop the node first to avoid a possible dict resize (due to
           eval loop reentrancy) and complications due to hash collision
           resolution. */
        int res = _odict_clear_node((PyODictObject *)od, node, key, hash);
        if (res < 0) {
            goto done;
        }
        /* Now delete the value from the dict. */
        if (_PyDict_Pop_KnownHash((PyDictObject *)od, key, hash,
                                  &value) == 0) {
            value = Py_NewRef(failobj);
        }
    }
    else if (value == NULL && !PyErr_Occurred()) {
        /* Apply the fallback value, if necessary. */
        if (failobj) {
            value = Py_NewRef(failobj);
        }
        else {
            PyErr_SetObject(PyExc_KeyError, key);
        }
    }
    Py_END_CRITICAL_SECTION();
done:

    return value;
}

/* Skips __missing__() calls. */
/*[clinic input]
OrderedDict.pop

    key: object
    default: object = NULL

od.pop(key[,default]) -> v, remove specified key and return the corresponding value.

If the key is not found, return the default if given; otherwise,
raise a KeyError.
[clinic start generated code]*/

static PyObject *
OrderedDict_pop_impl(PyODictObject *self, PyObject *key,
                     PyObject *default_value)
/*[clinic end generated code: output=7a6447d104e7494b input=7efe36601007dff7]*/
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1)
        return NULL;
    return _odict_popkey_hash((PyObject *)self, key, default_value, hash);
}


/* popitem() */

/*[clinic input]
OrderedDict.popitem

    last: bool = True

Remove and return a (key, value) pair from the dictionary.

Pairs are returned in LIFO order if last is true or FIFO order if false.
[clinic start generated code]*/

static PyObject *
OrderedDict_popitem_impl(PyODictObject *self, int last)
/*[clinic end generated code: output=98e7d986690d49eb input=d992ac5ee8305e1a]*/
{
    PyObject *key, *value, *item = NULL;
    _ODictNode *node;

    /* pull the item */

    if (_odict_EMPTY(self)) {
        PyErr_SetString(PyExc_KeyError, "dictionary is empty");
        return NULL;
    }

    node = last ? _odict_LAST(self) : _odict_FIRST(self);
    key = Py_NewRef(_odictnode_KEY(node));
    value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node));
    if (value == NULL)
        return NULL;
    item = PyTuple_Pack(2, key, value);
    Py_DECREF(key);
    Py_DECREF(value);
    return item;
}

/* keys() */

/* MutableMapping.keys() does not have a docstring. */
PyDoc_STRVAR(odict_keys__doc__, "");

static PyObject * odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */

/* values() */

/* MutableMapping.values() does not have a docstring. */
PyDoc_STRVAR(odict_values__doc__, "");

static PyObject * odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */

/* items() */

/* MutableMapping.items() does not have a docstring. */
PyDoc_STRVAR(odict_items__doc__, "");

static PyObject * odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored));  /* forward */

/* update() */

/* MutableMapping.update() does not have a docstring. */
PyDoc_STRVAR(odict_update__doc__, "");

/* forward */
static PyObject * mutablemapping_update(PyObject *, PyObject *, PyObject *);

#define odict_update mutablemapping_update

/* clear() */

PyDoc_STRVAR(odict_clear__doc__,
             "od.clear() -> None.  Remove all items from od.");

static PyObject *
odict_clear(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
{
    PyDict_Clear((PyObject *)od);
    _odict_clear_nodes(od);
    Py_RETURN_NONE;
}

/* copy() */

/* forward */
static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
                                      Py_hash_t);

PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od");

static PyObject *
odict_copy(register PyODictObject *od, PyObject *Py_UNUSED(ignored))
{
    _ODictNode *node;
    PyObject *od_copy;

    if (PyODict_CheckExact(od))
        od_copy = PyODict_New();
    else
        od_copy = _PyObject_CallNoArgs((PyObject *)Py_TYPE(od));
    if (od_copy == NULL)
        return NULL;

    if (PyODict_CheckExact(od)) {
        _odict_FOREACH(od, node) {
            PyObject *key = _odictnode_KEY(node);
            PyObject *value = _odictnode_VALUE(node, od);
            if (value == NULL) {
                if (!PyErr_Occurred())
                    PyErr_SetObject(PyExc_KeyError, key);
                goto fail;
            }
            if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value,
                                           _odictnode_HASH(node)) != 0)
                goto fail;
        }
    }
    else {
        _odict_FOREACH(od, node) {
            int res;
            PyObject *value = PyObject_GetItem((PyObject *)od,
                                               _odictnode_KEY(node));
            if (value == NULL)
                goto fail;
            res = PyObject_SetItem((PyObject *)od_copy,
                                   _odictnode_KEY(node), value);
            Py_DECREF(value);
            if (res != 0)
                goto fail;
        }
    }
    return od_copy;

fail:
    Py_DECREF(od_copy);
    return NULL;
}

/* __reversed__() */

PyDoc_STRVAR(odict_reversed__doc__, "od.__reversed__() <==> reversed(od)");

#define _odict_ITER_REVERSED 1
#define _odict_ITER_KEYS 2
#define _odict_ITER_VALUES 4
#define _odict_ITER_ITEMS (_odict_ITER_KEYS|_odict_ITER_VALUES)

/* forward */
static PyObject * odictiter_new(PyODictObject *, int);

static PyObject *
odict_reversed(PyODictObject *od, PyObject *Py_UNUSED(ignored))
{
    return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED);
}


/* move_to_end() */

/*[clinic input]
OrderedDict.move_to_end

    key: object
    last: bool = True

Move an existing element to the end (or beginning if last is false).

Raise KeyError if the element does not exist.
[clinic start generated code]*/

static PyObject *
OrderedDict_move_to_end_impl(PyODictObject *self, PyObject *key, int last)
/*[clinic end generated code: output=fafa4c5cc9b92f20 input=d6ceff7132a2fcd7]*/
{
    _ODictNode *node;

    if (_odict_EMPTY(self)) {
        PyErr_SetObject(PyExc_KeyError, key);
        return NULL;
    }
    node = last ? _odict_LAST(self) : _odict_FIRST(self);
    if (key != _odictnode_KEY(node)) {
        node = _odict_find_node(self, key);
        if (node == NULL) {
            if (!PyErr_Occurred())
                PyErr_SetObject(PyExc_KeyError, key);
            return NULL;
        }
        if (last) {
            /* Only move if not already the last one. */
            if (node != _odict_LAST(self)) {
                _odict_remove_node(self, node);
                _odict_add_tail(self, node);
            }
        }
        else {
            /* Only move if not already the first one. */
            if (node != _odict_FIRST(self)) {
                _odict_remove_node(self, node);
                _odict_add_head(self, node);
            }
        }
    }
    Py_RETURN_NONE;
}


/* tp_methods */

static PyMethodDef odict_methods[] = {

    /* overridden dict methods */
    ORDEREDDICT_FROMKEYS_METHODDEF
    {"__sizeof__",      (PyCFunction)odict_sizeof,      METH_NOARGS,
     odict_sizeof__doc__},
    {"__reduce__",      (PyCFunction)odict_reduce,      METH_NOARGS,
     odict_reduce__doc__},
    ORDEREDDICT_SETDEFAULT_METHODDEF
    ORDEREDDICT_POP_METHODDEF
    ORDEREDDICT_POPITEM_METHODDEF
    {"keys",            odictkeys_new,                  METH_NOARGS,
     odict_keys__doc__},
    {"values",          odictvalues_new,                METH_NOARGS,
     odict_values__doc__},
    {"items",           odictitems_new,                 METH_NOARGS,
     odict_items__doc__},
    {"update",          _PyCFunction_CAST(odict_update), METH_VARARGS | METH_KEYWORDS,
     odict_update__doc__},
    {"clear",           (PyCFunction)odict_clear,       METH_NOARGS,
     odict_clear__doc__},
    {"copy",            (PyCFunction)odict_copy,        METH_NOARGS,
     odict_copy__doc__},

    /* new methods */
    {"__reversed__",    (PyCFunction)odict_reversed,    METH_NOARGS,
     odict_reversed__doc__},
    ORDEREDDICT_MOVE_TO_END_METHODDEF

    {NULL,              NULL}   /* sentinel */
};


/* ----------------------------------------------
 * OrderedDict members
 */

/* tp_getset */

static PyGetSetDef odict_getset[] = {
    {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
    {NULL}
};

/* ----------------------------------------------
 * OrderedDict type slot methods
 */

/* tp_dealloc */

static void
odict_dealloc(PyODictObject *self)
{
    PyObject_GC_UnTrack(self);
    Py_TRASHCAN_BEGIN(self, odict_dealloc)

    Py_XDECREF(self->od_inst_dict);
    if (self->od_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *)self);

    _odict_clear_nodes(self);
    PyDict_Type.tp_dealloc((PyObject *)self);

    Py_TRASHCAN_END
}

/* tp_repr */

static PyObject *
odict_repr(PyODictObject *self)
{
    int i;
    PyObject *result = NULL, *dcopy = NULL;

    if (PyODict_SIZE(self) == 0)
        return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self)));

    i = Py_ReprEnter((PyObject *)self);
    if (i != 0) {
        return i > 0 ? PyUnicode_FromString("...") : NULL;
    }

    dcopy = PyDict_Copy((PyObject *)self);
    if (dcopy == NULL) {
        goto Done;
    }

    result = PyUnicode_FromFormat("%s(%R)",
                                  _PyType_Name(Py_TYPE(self)),
                                  dcopy);
    Py_DECREF(dcopy);

Done:
    Py_ReprLeave((PyObject *)self);
    return result;
}

/* tp_doc */

PyDoc_STRVAR(odict_doc,
        "Dictionary that remembers insertion order");

/* tp_traverse */

static int
odict_traverse(PyODictObject *od, visitproc visit, void *arg)
{
    _ODictNode *node;

    Py_VISIT(od->od_inst_dict);
    _odict_FOREACH(od, node) {
        Py_VISIT(_odictnode_KEY(node));
    }
    return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
}

/* tp_clear */

static int
odict_tp_clear(PyODictObject *od)
{
    Py_CLEAR(od->od_inst_dict);
    PyDict_Clear((PyObject *)od);
    _odict_clear_nodes(od);
    return 0;
}

/* tp_richcompare */

static PyObject *
odict_richcompare(PyObject *v, PyObject *w, int op)
{
    if (!PyODict_Check(v) || !PyDict_Check(w)) {
        Py_RETURN_NOTIMPLEMENTED;
    }

    if (op == Py_EQ || op == Py_NE) {
        PyObject *res, *cmp;
        int eq;

        cmp = PyDict_Type.tp_richcompare(v, w, op);
        if (cmp == NULL)
            return NULL;
        if (!PyODict_Check(w))
            return cmp;
        if (op == Py_EQ && cmp == Py_False)
            return cmp;
        if (op == Py_NE && cmp == Py_True)
            return cmp;
        Py_DECREF(cmp);

        /* Try comparing odict keys. */
        eq = _odict_keys_equal((PyODictObject *)v, (PyODictObject *)w);
        if (eq < 0)
            return NULL;

        res = (eq == (op == Py_EQ)) ? Py_True : Py_False;
        return Py_NewRef(res);
    } else {
        Py_RETURN_NOTIMPLEMENTED;
    }
}

/* tp_iter */

static PyObject *
odict_iter(PyODictObject *od)
{
    return odictiter_new(od, _odict_ITER_KEYS);
}

/* tp_init */

static int
odict_init(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *res;
    Py_ssize_t len = PyObject_Length(args);

    if (len == -1)
        return -1;
    if (len > 1) {
        const char *msg = "expected at most 1 arguments, got %zd";
        PyErr_Format(PyExc_TypeError, msg, len);
        return -1;
    }

    /* __init__() triggering update() is just the way things are! */
    res = odict_update(self, args, kwds);
    if (res == NULL) {
        return -1;
    } else {
        Py_DECREF(res);
        return 0;
    }
}

/* PyODict_Type */

PyTypeObject PyODict_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "collections.OrderedDict",                  /* tp_name */
    sizeof(PyODictObject),                      /* tp_basicsize */
    0,                                          /* tp_itemsize */
    (destructor)odict_dealloc,                  /* tp_dealloc */
    0,                                          /* tp_vectorcall_offset */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_as_async */
    (reprfunc)odict_repr,                       /* tp_repr */
    &odict_as_number,                           /* tp_as_number */
    0,                                          /* tp_as_sequence */
    &odict_as_mapping,                          /* 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 | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,/* tp_flags */
    odict_doc,                                  /* tp_doc */
    (traverseproc)odict_traverse,               /* tp_traverse */
    (inquiry)odict_tp_clear,                    /* tp_clear */
    (richcmpfunc)odict_richcompare,             /* tp_richcompare */
    offsetof(PyODictObject, od_weakreflist),    /* tp_weaklistoffset */
    (getiterfunc)odict_iter,                    /* tp_iter */
    0,                                          /* tp_iternext */
    odict_methods,                              /* tp_methods */
    0,                                          /* tp_members */
    odict_getset,                               /* tp_getset */
    &PyDict_Type,                               /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    offsetof(PyODictObject, od_inst_dict),      /* tp_dictoffset */
    (initproc)odict_init,                       /* tp_init */
    PyType_GenericAlloc,                        /* tp_alloc */
    0,                                          /* tp_new */
    0,                                          /* tp_free */
};


/* ----------------------------------------------
 * the public OrderedDict API
 */

PyObject *
PyODict_New(void)
{
    return PyDict_Type.tp_new(&PyODict_Type, NULL, NULL);
}

static int
_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value,
                           Py_hash_t hash)
{
    int res = _PyDict_SetItem_KnownHash(od, key, value, hash);
    if (res == 0) {
        res = _odict_add_new_node((PyODictObject *)od, key, hash);
        if (res < 0) {
            /* Revert setting the value on the dict */
            PyObject *exc = PyErr_GetRaisedException();
            (void) _PyDict_DelItem_KnownHash(od, key, hash);
            _PyErr_ChainExceptions1(exc);
        }
    }
    return res;
}

int
PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value)
{
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1)
        return -1;
    return _PyODict_SetItem_KnownHash(od, key, value, hash);
}

int
PyODict_DelItem(PyObject *od, PyObject *key)
{
    int res;
    Py_hash_t hash = PyObject_Hash(key);
    if (hash == -1)
        return -1;
    res = _odict_clear_node((PyODictObject *)od, NULL, key, hash);
    if (res < 0)
        return -1;
    return _PyDict_DelItem_KnownHash(od, key, hash);
}


/* -------------------------------------------
 * The OrderedDict views (keys/values/items)
 */

typedef struct {
    PyObject_HEAD
    int kind;
    PyODictObject *di_odict;
    Py_ssize_t di_size;
    size_t di_state;
    PyObject *di_current;
    PyObject *di_result; /* reusable result tuple for iteritems */
} odictiterobject;

static void
odictiter_dealloc(odictiterobject *di)
{
    _PyObject_GC_UNTRACK(di);
    Py_XDECREF(di->di_odict);
    Py_XDECREF(di->di_current);
    if ((di->kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
        Py_DECREF(di->di_result);
    }
    PyObject_GC_Del(di);
}

static int
odictiter_traverse(odictiterobject *di, visitproc visit, void *arg)
{
    Py_VISIT(di->di_odict);
    Py_VISIT(di->di_current);  /* A key could be any type, not just str. */
    Py_VISIT(di->di_result);
    return 0;
}

/* In order to protect against modifications during iteration, we track
 * the current key instead of the current node. */
static PyObject *
odictiter_nextkey(odictiterobject *di)
{
    PyObject *key = NULL;
    _ODictNode *node;
    int reversed = di->kind & _odict_ITER_REVERSED;

    if (di->di_odict == NULL)
        return NULL;
    if (di->di_current == NULL)
        goto done;  /* We're already done. */

    /* Check for unsupported changes. */
    if (di->di_odict->od_state != di->di_state) {
        PyErr_SetString(PyExc_RuntimeError,
                        "OrderedDict mutated during iteration");
        goto done;
    }
    if (di->di_size != PyODict_SIZE(di->di_odict)) {
        PyErr_SetString(PyExc_RuntimeError,
                        "OrderedDict changed size during iteration");
        di->di_size = -1; /* Make this state sticky */
        return NULL;
    }

    /* Get the key. */
    node = _odict_find_node(di->di_odict, di->di_current);
    if (node == NULL) {
        if (!PyErr_Occurred())
            PyErr_SetObject(PyExc_KeyError, di->di_current);
        /* Must have been deleted. */
        Py_CLEAR(di->di_current);
        return NULL;
    }
    key = di->di_current;

    /* Advance to the next key. */
    node = reversed ? _odictnode_PREV(node) : _odictnode_NEXT(node);
    if (node == NULL) {
        /* Reached the end. */
        di->di_current = NULL;
    }
    else {
        di->di_current = Py_NewRef(_odictnode_KEY(node));
    }

    return key;

done:
    Py_CLEAR(di->di_odict);
    return key;
}

static PyObject *
odictiter_iternext(odictiterobject *di)
{
    PyObject *result, *value;
    PyObject *key = odictiter_nextkey(di);  /* new reference */

    if (key == NULL)
        return NULL;

    /* Handle the keys case. */
    if (! (di->kind & _odict_ITER_VALUES)) {
        return key;
    }

    value = PyODict_GetItem((PyObject *)di->di_odict, key);  /* borrowed */
    if (value == NULL) {
        if (!PyErr_Occurred())
            PyErr_SetObject(PyExc_KeyError, key);
        Py_DECREF(key);
        goto done;
    }
    Py_INCREF(value);

    /* Handle the values case. */
    if (!(di->kind & _odict_ITER_KEYS)) {
        Py_DECREF(key);
        return value;
    }

    /* Handle the items case. */
    result = di->di_result;

    if (Py_REFCNT(result) == 1) {
        /* not in use so we can reuse it
         * (the common case during iteration) */
        Py_INCREF(result);
        Py_DECREF(PyTuple_GET_ITEM(result, 0));  /* borrowed */
        Py_DECREF(PyTuple_GET_ITEM(result, 1));  /* borrowed */
        // bpo-42536: The GC may have untracked this result tuple. Since we're
        // recycling it, make sure it's tracked again:
        if (!_PyObject_GC_IS_TRACKED(result)) {
            _PyObject_GC_TRACK(result);
        }
    }
    else {
        result = PyTuple_New(2);
        if (result == NULL) {
            Py_DECREF(key);
            Py_DECREF(value);
            goto done;
        }
    }

    PyTuple_SET_ITEM(result, 0, key);  /* steals reference */
    PyTuple_SET_ITEM(result, 1, value);  /* steals reference */
    return result;

done:
    Py_CLEAR(di->di_current);
    Py_CLEAR(di->di_odict);
    return NULL;
}

/* No need for tp_clear because odictiterobject is not mutable. */

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

static PyObject *
odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
{
    /* copy the iterator state */
    odictiterobject tmp = *di;
    Py_XINCREF(tmp.di_odict);
    Py_XINCREF(tmp.di_current);

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

static PyMethodDef odictiter_methods[] = {
    {"__reduce__", (PyCFunction)odictiter_reduce, METH_NOARGS, reduce_doc},
    {NULL,              NULL}           /* sentinel */
};

PyTypeObject PyODictIter_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "odict_iterator",                         /* tp_name */
    sizeof(odictiterobject),                  /* tp_basicsize */
    0,                                        /* tp_itemsize */
    /* methods */
    (destructor)odictiter_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 */
    (traverseproc)odictiter_traverse,         /* tp_traverse */
    0,                                        /* tp_clear */
    0,                                        /* tp_richcompare */
    0,                                        /* tp_weaklistoffset */
    PyObject_SelfIter,                        /* tp_iter */
    (iternextfunc)odictiter_iternext,         /* tp_iternext */
    odictiter_methods,                        /* tp_methods */
    0,
};

static PyObject *
odictiter_new(PyODictObject *od, int kind)
{
    odictiterobject *di;
    _ODictNode *node;
    int reversed = kind & _odict_ITER_REVERSED;

    di = PyObject_GC_New(odictiterobject, &PyODictIter_Type);
    if (di == NULL)
        return NULL;

    if ((kind & _odict_ITER_ITEMS) == _odict_ITER_ITEMS) {
        di->di_result = PyTuple_Pack(2, Py_None, Py_None);
        if (di->di_result == NULL) {
            Py_DECREF(di);
            return NULL;
        }
    }
    else {
        di->di_result = NULL;
    }

    di->kind = kind;
    node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
    di->di_current = node ? Py_NewRef(_odictnode_KEY(node)) : NULL;
    di->di_size = PyODict_SIZE(od);
    di->di_state = od->od_state;
    di->di_odict = (PyODictObject*)Py_NewRef(od);

    _PyObject_GC_TRACK(di);
    return (PyObject *)di;
}

/* keys() */

static PyObject *
odictkeys_iter(_PyDictViewObject *dv)
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_KEYS);
}

static PyObject *
odictkeys_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_KEYS|_odict_ITER_REVERSED);
}

static PyMethodDef odictkeys_methods[] = {
    {"__reversed__", (PyCFunction)odictkeys_reversed, METH_NOARGS, NULL},
    {NULL,          NULL}           /* sentinel */
};

PyTypeObject PyODictKeys_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "odict_keys",                             /* tp_name */
    0,                                        /* tp_basicsize */
    0,                                        /* tp_itemsize */
    0,                                        /* 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 */
    0,                                        /* tp_getattro */
    0,                                        /* tp_setattro */
    0,                                        /* tp_as_buffer */
    0,                                        /* tp_flags */
    0,                                        /* tp_doc */
    0,                                        /* tp_traverse */
    0,                                        /* tp_clear */
    0,                                        /* tp_richcompare */
    0,                                        /* tp_weaklistoffset */
    (getiterfunc)odictkeys_iter,              /* tp_iter */
    0,                                        /* tp_iternext */
    odictkeys_methods,                        /* tp_methods */
    0,                                        /* tp_members */
    0,                                        /* tp_getset */
    &PyDictKeys_Type,                         /* tp_base */
};

static PyObject *
odictkeys_new(PyObject *od, PyObject *Py_UNUSED(ignored))
{
    return _PyDictView_New(od, &PyODictKeys_Type);
}

/* items() */

static PyObject *
odictitems_iter(_PyDictViewObject *dv)
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_KEYS|_odict_ITER_VALUES);
}

static PyObject *
odictitems_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_KEYS|_odict_ITER_VALUES|_odict_ITER_REVERSED);
}

static PyMethodDef odictitems_methods[] = {
    {"__reversed__", (PyCFunction)odictitems_reversed, METH_NOARGS, NULL},
    {NULL,          NULL}           /* sentinel */
};

PyTypeObject PyODictItems_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "odict_items",                            /* tp_name */
    0,                                        /* tp_basicsize */
    0,                                        /* tp_itemsize */
    0,                                        /* 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 */
    0,                                        /* tp_getattro */
    0,                                        /* tp_setattro */
    0,                                        /* tp_as_buffer */
    0,                                        /* tp_flags */
    0,                                        /* tp_doc */
    0,                                        /* tp_traverse */
    0,                                        /* tp_clear */
    0,                                        /* tp_richcompare */
    0,                                        /* tp_weaklistoffset */
    (getiterfunc)odictitems_iter,             /* tp_iter */
    0,                                        /* tp_iternext */
    odictitems_methods,                       /* tp_methods */
    0,                                        /* tp_members */
    0,                                        /* tp_getset */
    &PyDictItems_Type,                        /* tp_base */
};

static PyObject *
odictitems_new(PyObject *od, PyObject *Py_UNUSED(ignored))
{
    return _PyDictView_New(od, &PyODictItems_Type);
}

/* values() */

static PyObject *
odictvalues_iter(_PyDictViewObject *dv)
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_VALUES);
}

static PyObject *
odictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored))
{
    if (dv->dv_dict == NULL) {
        Py_RETURN_NONE;
    }
    return odictiter_new((PyODictObject *)dv->dv_dict,
            _odict_ITER_VALUES|_odict_ITER_REVERSED);
}

static PyMethodDef odictvalues_methods[] = {
    {"__reversed__", (PyCFunction)odictvalues_reversed, METH_NOARGS, NULL},
    {NULL,          NULL}           /* sentinel */
};

PyTypeObject PyODictValues_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "odict_values",                           /* tp_name */
    0,                                        /* tp_basicsize */
    0,                                        /* tp_itemsize */
    0,                                        /* 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 */
    0,                                        /* tp_getattro */
    0,                                        /* tp_setattro */
    0,                                        /* tp_as_buffer */
    0,                                        /* tp_flags */
    0,                                        /* tp_doc */
    0,                                        /* tp_traverse */
    0,                                        /* tp_clear */
    0,                                        /* tp_richcompare */
    0,                                        /* tp_weaklistoffset */
    (getiterfunc)odictvalues_iter,            /* tp_iter */
    0,                                        /* tp_iternext */
    odictvalues_methods,                      /* tp_methods */
    0,                                        /* tp_members */
    0,                                        /* tp_getset */
    &PyDictValues_Type,                       /* tp_base */
};

static PyObject *
odictvalues_new(PyObject *od, PyObject *Py_UNUSED(ignored))
{
    return _PyDictView_New(od, &PyODictValues_Type);
}


/* ----------------------------------------------
   MutableMapping implementations

Mapping:

============ ===========
method       uses
============ ===========
__contains__ __getitem__
__eq__       items
__getitem__  +
__iter__     +
__len__      +
__ne__       __eq__
get          __getitem__
items        ItemsView
keys         KeysView
values       ValuesView
============ ===========

ItemsView uses __len__, __iter__, and __getitem__.
KeysView uses __len__, __iter__, and __contains__.
ValuesView uses __len__, __iter__, and __getitem__.

MutableMapping:

============ ===========
method       uses
============ ===========
__delitem__  +
__setitem__  +
clear        popitem
pop          __getitem__
             __delitem__
popitem      __iter__
             _getitem__
             __delitem__
setdefault   __getitem__
             __setitem__
update       __setitem__
============ ===========
*/

static int
mutablemapping_add_pairs(PyObject *self, PyObject *pairs)
{
    PyObject *pair, *iterator, *unexpected;
    int res = 0;

    iterator = PyObject_GetIter(pairs);
    if (iterator == NULL)
        return -1;
    PyErr_Clear();

    while ((pair = PyIter_Next(iterator)) != NULL) {
        /* could be more efficient (see UNPACK_SEQUENCE in ceval.c) */
        PyObject *key = NULL, *value = NULL;
        PyObject *pair_iterator = PyObject_GetIter(pair);
        if (pair_iterator == NULL)
            goto Done;

        key = PyIter_Next(pair_iterator);
        if (key == NULL) {
            if (!PyErr_Occurred())
                PyErr_SetString(PyExc_ValueError,
                                "need more than 0 values to unpack");
            goto Done;
        }

        value = PyIter_Next(pair_iterator);
        if (value == NULL) {
            if (!PyErr_Occurred())
                PyErr_SetString(PyExc_ValueError,
                                "need more than 1 value to unpack");
            goto Done;
        }

        unexpected = PyIter_Next(pair_iterator);
        if (unexpected != NULL) {
            Py_DECREF(unexpected);
            PyErr_SetString(PyExc_ValueError,
                            "too many values to unpack (expected 2)");
            goto Done;
        }
        else if (PyErr_Occurred())
            goto Done;

        res = PyObject_SetItem(self, key, value);

Done:
        Py_DECREF(pair);
        Py_XDECREF(pair_iterator);
        Py_XDECREF(key);
        Py_XDECREF(value);
        if (PyErr_Occurred())
            break;
    }
    Py_DECREF(iterator);

    if (res < 0 || PyErr_Occurred() != NULL)
        return -1;
    else
        return 0;
}

static int
mutablemapping_update_arg(PyObject *self, PyObject *arg)
{
    int res = 0;
    if (PyDict_CheckExact(arg)) {
        PyObject *items = PyDict_Items(arg);
        if (items == NULL) {
            return -1;
        }
        res = mutablemapping_add_pairs(self, items);
        Py_DECREF(items);
        return res;
    }
    PyObject *func;
    if (PyObject_GetOptionalAttr(arg, &_Py_ID(keys), &func) < 0) {
        return -1;
    }
    if (func != NULL) {
        PyObject *keys = _PyObject_CallNoArgs(func);
        Py_DECREF(func);
        if (keys == NULL) {
            return -1;
        }
        PyObject *iterator = PyObject_GetIter(keys);
        Py_DECREF(keys);
        if (iterator == NULL) {
            return -1;
        }
        PyObject *key;
        while (res == 0 && (key = PyIter_Next(iterator))) {
            PyObject *value = PyObject_GetItem(arg, key);
            if (value != NULL) {
                res = PyObject_SetItem(self, key, value);
                Py_DECREF(value);
            }
            else {
                res = -1;
            }
            Py_DECREF(key);
        }
        Py_DECREF(iterator);
        if (res != 0 || PyErr_Occurred()) {
            return -1;
        }
        return 0;
    }
    if (PyObject_GetOptionalAttr(arg, &_Py_ID(items), &func) < 0) {
        return -1;
    }
    if (func != NULL) {
        PyObject *items = _PyObject_CallNoArgs(func);
        Py_DECREF(func);
        if (items == NULL) {
            return -1;
        }
        res = mutablemapping_add_pairs(self, items);
        Py_DECREF(items);
        return res;
    }
    res = mutablemapping_add_pairs(self, arg);
    return res;
}

static PyObject *
mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
{
    int res;
    /* first handle args, if any */
    assert(args == NULL || PyTuple_Check(args));
    Py_ssize_t len = (args != NULL) ? PyTuple_GET_SIZE(args) : 0;
    if (len > 1) {
        const char *msg = "update() takes at most 1 positional argument (%zd given)";
        PyErr_Format(PyExc_TypeError, msg, len);
        return NULL;
    }

    if (len) {
        PyObject *other = PyTuple_GET_ITEM(args, 0);  /* borrowed reference */
        assert(other != NULL);
        Py_INCREF(other);
        res = mutablemapping_update_arg(self, other);
        Py_DECREF(other);
        if (res < 0) {
            return NULL;
        }
    }

    /* now handle kwargs */
    assert(kwargs == NULL || PyDict_Check(kwargs));
    if (kwargs != NULL && PyDict_GET_SIZE(kwargs)) {
        PyObject *items = PyDict_Items(kwargs);
        if (items == NULL)
            return NULL;
        res = mutablemapping_add_pairs(self, items);
        Py_DECREF(items);
        if (res == -1)
            return NULL;
    }

    Py_RETURN_NONE;
}
