#ifndef Py_INTERNAL_HAMT_H1#define Py_INTERNAL_HAMT_H23#ifndef Py_BUILD_CORE4# error "this header requires Py_BUILD_CORE define"5#endif678/*9HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes10the exact position of the key in one level of the tree. Since we're using1132 bit hashes, we can have at most 7 such levels. Although if there are12two distinct keys with equal hashes, they will have to occupy the same13cell in the 7th level of the tree -- so we'd put them in a "collision" node.14Which brings the total possible tree depth to 8. Read more about the actual15layout of the HAMT tree in `hamt.c`.1617This constant is used to define a datastucture for storing iteration state.18*/19#define _Py_HAMT_MAX_TREE_DEPTH 8202122extern PyTypeObject _PyHamt_Type;23extern PyTypeObject _PyHamt_ArrayNode_Type;24extern PyTypeObject _PyHamt_BitmapNode_Type;25extern PyTypeObject _PyHamt_CollisionNode_Type;26extern PyTypeObject _PyHamtKeys_Type;27extern PyTypeObject _PyHamtValues_Type;28extern PyTypeObject _PyHamtItems_Type;293031/* other API */3233#define PyHamt_Check(o) Py_IS_TYPE((o), &_PyHamt_Type)343536/* Abstract tree node. */37typedef struct {38PyObject_HEAD39} PyHamtNode;404142/* An HAMT immutable mapping collection. */43typedef struct {44PyObject_HEAD45PyHamtNode *h_root;46PyObject *h_weakreflist;47Py_ssize_t h_count;48} PyHamtObject;495051typedef struct {52PyObject_VAR_HEAD53uint32_t b_bitmap;54PyObject *b_array[1];55} PyHamtNode_Bitmap;565758/* A struct to hold the state of depth-first traverse of the tree.5960HAMT is an immutable collection. Iterators will hold a strong reference61to it, and every node in the HAMT has strong references to its children.6263So for iterators, we can implement zero allocations and zero reference64inc/dec depth-first iteration.6566- i_nodes: an array of seven pointers to tree nodes67- i_level: the current node in i_nodes68- i_pos: an array of positions within nodes in i_nodes.69*/70typedef struct {71PyHamtNode *i_nodes[_Py_HAMT_MAX_TREE_DEPTH];72Py_ssize_t i_pos[_Py_HAMT_MAX_TREE_DEPTH];73int8_t i_level;74} PyHamtIteratorState;757677/* Base iterator object.7879Contains the iteration state, a pointer to the HAMT tree,80and a pointer to the 'yield function'. The latter is a simple81function that returns a key/value tuple for the 'Items' iterator,82just a key for the 'Keys' iterator, and a value for the 'Values'83iterator.84*/85typedef struct {86PyObject_HEAD87PyHamtObject *hi_obj;88PyHamtIteratorState hi_iter;89binaryfunc hi_yield;90} PyHamtIterator;919293/* Create a new HAMT immutable mapping. */94PyHamtObject * _PyHamt_New(void);9596/* Return a new collection based on "o", but with an additional97key/val pair. */98PyHamtObject * _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val);99100/* Return a new collection based on "o", but without "key". */101PyHamtObject * _PyHamt_Without(PyHamtObject *o, PyObject *key);102103/* Find "key" in the "o" collection.104105Return:106- -1: An error occurred.107- 0: "key" wasn't found in "o".108- 1: "key" is in "o"; "*val" is set to its value (a borrowed ref).109*/110int _PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val);111112/* Check if "v" is equal to "w".113114Return:115- 0: v != w116- 1: v == w117- -1: An error occurred.118*/119int _PyHamt_Eq(PyHamtObject *v, PyHamtObject *w);120121/* Return the size of "o"; equivalent of "len(o)". */122Py_ssize_t _PyHamt_Len(PyHamtObject *o);123124/* Return a Keys iterator over "o". */125PyObject * _PyHamt_NewIterKeys(PyHamtObject *o);126127/* Return a Values iterator over "o". */128PyObject * _PyHamt_NewIterValues(PyHamtObject *o);129130/* Return a Items iterator over "o". */131PyObject * _PyHamt_NewIterItems(PyHamtObject *o);132133#endif /* !Py_INTERNAL_HAMT_H */134135136