(root)/
Python-3.11.7/
Include/
internal/
pycore_hamt.h
       1  #ifndef Py_INTERNAL_HAMT_H
       2  #define Py_INTERNAL_HAMT_H
       3  
       4  #ifndef Py_BUILD_CORE
       5  #  error "this header requires Py_BUILD_CORE define"
       6  #endif
       7  
       8  
       9  /*
      10  HAMT tree is shaped by hashes of keys. Every group of 5 bits of a hash denotes
      11  the exact position of the key in one level of the tree. Since we're using
      12  32 bit hashes, we can have at most 7 such levels. Although if there are
      13  two distinct keys with equal hashes, they will have to occupy the same
      14  cell in the 7th level of the tree -- so we'd put them in a "collision" node.
      15  Which brings the total possible tree depth to 8. Read more about the actual
      16  layout of the HAMT tree in `hamt.c`.
      17  
      18  This constant is used to define a datastucture for storing iteration state.
      19  */
      20  #define _Py_HAMT_MAX_TREE_DEPTH 8
      21  
      22  
      23  extern PyTypeObject _PyHamt_Type;
      24  extern PyTypeObject _PyHamt_ArrayNode_Type;
      25  extern PyTypeObject _PyHamt_BitmapNode_Type;
      26  extern PyTypeObject _PyHamt_CollisionNode_Type;
      27  extern PyTypeObject _PyHamtKeys_Type;
      28  extern PyTypeObject _PyHamtValues_Type;
      29  extern PyTypeObject _PyHamtItems_Type;
      30  
      31  /* runtime lifecycle */
      32  
      33  void _PyHamt_Fini(PyInterpreterState *);
      34  
      35  
      36  /* other API */
      37  
      38  #define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type)
      39  
      40  
      41  /* Abstract tree node. */
      42  typedef struct {
      43      PyObject_HEAD
      44  } PyHamtNode;
      45  
      46  
      47  /* An HAMT immutable mapping collection. */
      48  typedef struct {
      49      PyObject_HEAD
      50      PyHamtNode *h_root;
      51      PyObject *h_weakreflist;
      52      Py_ssize_t h_count;
      53  } PyHamtObject;
      54  
      55  
      56  /* A struct to hold the state of depth-first traverse of the tree.
      57  
      58     HAMT is an immutable collection.  Iterators will hold a strong reference
      59     to it, and every node in the HAMT has strong references to its children.
      60  
      61     So for iterators, we can implement zero allocations and zero reference
      62     inc/dec depth-first iteration.
      63  
      64     - i_nodes: an array of seven pointers to tree nodes
      65     - i_level: the current node in i_nodes
      66     - i_pos: an array of positions within nodes in i_nodes.
      67  */
      68  typedef struct {
      69      PyHamtNode *i_nodes[_Py_HAMT_MAX_TREE_DEPTH];
      70      Py_ssize_t i_pos[_Py_HAMT_MAX_TREE_DEPTH];
      71      int8_t i_level;
      72  } PyHamtIteratorState;
      73  
      74  
      75  /* Base iterator object.
      76  
      77     Contains the iteration state, a pointer to the HAMT tree,
      78     and a pointer to the 'yield function'.  The latter is a simple
      79     function that returns a key/value tuple for the 'Items' iterator,
      80     just a key for the 'Keys' iterator, and a value for the 'Values'
      81     iterator.
      82  */
      83  typedef struct {
      84      PyObject_HEAD
      85      PyHamtObject *hi_obj;
      86      PyHamtIteratorState hi_iter;
      87      binaryfunc hi_yield;
      88  } PyHamtIterator;
      89  
      90  
      91  /* Create a new HAMT immutable mapping. */
      92  PyHamtObject * _PyHamt_New(void);
      93  
      94  /* Return a new collection based on "o", but with an additional
      95     key/val pair. */
      96  PyHamtObject * _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val);
      97  
      98  /* Return a new collection based on "o", but without "key". */
      99  PyHamtObject * _PyHamt_Without(PyHamtObject *o, PyObject *key);
     100  
     101  /* Find "key" in the "o" collection.
     102  
     103     Return:
     104     - -1: An error occurred.
     105     - 0: "key" wasn't found in "o".
     106     - 1: "key" is in "o"; "*val" is set to its value (a borrowed ref).
     107  */
     108  int _PyHamt_Find(PyHamtObject *o, PyObject *key, PyObject **val);
     109  
     110  /* Check if "v" is equal to "w".
     111  
     112     Return:
     113     - 0: v != w
     114     - 1: v == w
     115     - -1: An error occurred.
     116  */
     117  int _PyHamt_Eq(PyHamtObject *v, PyHamtObject *w);
     118  
     119  /* Return the size of "o"; equivalent of "len(o)". */
     120  Py_ssize_t _PyHamt_Len(PyHamtObject *o);
     121  
     122  /* Return a Keys iterator over "o". */
     123  PyObject * _PyHamt_NewIterKeys(PyHamtObject *o);
     124  
     125  /* Return a Values iterator over "o". */
     126  PyObject * _PyHamt_NewIterValues(PyHamtObject *o);
     127  
     128  /* Return a Items iterator over "o". */
     129  PyObject * _PyHamt_NewIterItems(PyHamtObject *o);
     130  
     131  #endif /* !Py_INTERNAL_HAMT_H */