You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

4176 lines
105 KiB

  1. #include <stddef.h> /* For offsetof */
  2. #include "pythoncapi_compat.h"
  3. #include "_map.h"
  4. /*
  5. This file provides an implemention of an immutable mapping using the
  6. Hash Array Mapped Trie (or HAMT) datastructure.
  7. This design allows to have:
  8. 1. Efficient copy: immutable mappings can be copied by reference,
  9. making it an O(1) operation.
  10. 2. Efficient mutations: due to structural sharing, only a portion of
  11. the trie needs to be copied when the collection is mutated. The
  12. cost of set/delete operations is O(log N).
  13. 3. Efficient lookups: O(log N).
  14. (where N is number of key/value items in the immutable mapping.)
  15. HAMT
  16. ====
  17. The core idea of HAMT is that the shape of the trie is encoded into the
  18. hashes of keys.
  19. Say we want to store a K/V pair in our mapping. First, we calculate the
  20. hash of K, let's say it's 19830128, or in binary:
  21. 0b1001011101001010101110000 = 19830128
  22. Now let's partition this bit representation of the hash into blocks of
  23. 5 bits each:
  24. 0b00_00000_10010_11101_00101_01011_10000 = 19830128
  25. (6) (5) (4) (3) (2) (1)
  26. Each block of 5 bits represents a number between 0 and 31. So if we have
  27. a tree that consists of nodes, each of which is an array of 32 pointers,
  28. those 5-bit blocks will encode a position on a single tree level.
  29. For example, storing the key K with hash 19830128, results in the following
  30. tree structure:
  31. (array of 32 pointers)
  32. +---+ -- +----+----+----+ -- +----+
  33. root node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b10000 = 16 (1)
  34. (level 1) +---+ -- +----+----+----+ -- +----+
  35. |
  36. +---+ -- +----+----+----+ -- +----+
  37. a 2nd level node | 0 | .. | 10 | 11 | 12 | .. | 31 | 0b01011 = 11 (2)
  38. +---+ -- +----+----+----+ -- +----+
  39. |
  40. +---+ -- +----+----+----+ -- +----+
  41. a 3rd level node | 0 | .. | 04 | 05 | 06 | .. | 31 | 0b00101 = 5 (3)
  42. +---+ -- +----+----+----+ -- +----+
  43. |
  44. +---+ -- +----+----+----+----+
  45. a 4th level node | 0 | .. | 04 | 29 | 30 | 31 | 0b11101 = 29 (4)
  46. +---+ -- +----+----+----+----+
  47. |
  48. +---+ -- +----+----+----+ -- +----+
  49. a 5th level node | 0 | .. | 17 | 18 | 19 | .. | 31 | 0b10010 = 18 (5)
  50. +---+ -- +----+----+----+ -- +----+
  51. |
  52. +--------------+
  53. |
  54. +---+ -- +----+----+----+ -- +----+
  55. a 6th level node | 0 | .. | 15 | 16 | 17 | .. | 31 | 0b00000 = 0 (6)
  56. +---+ -- +----+----+----+ -- +----+
  57. |
  58. V -- our value (or collision)
  59. To rehash: for a K/V pair, the hash of K encodes where in the tree V will
  60. be stored.
  61. To optimize memory footprint and handle hash collisions, our implementation
  62. uses three different types of nodes:
  63. * A Bitmap node;
  64. * An Array node;
  65. * A Collision node.
  66. Because we implement an immutable dictionary, our nodes are also
  67. immutable. Therefore, when we need to modify a node, we copy it, and
  68. do that modification to the copy.
  69. Array Nodes
  70. -----------
  71. These nodes are very simple. Essentially they are arrays of 32 pointers
  72. we used to illustrate the high-level idea in the previous section.
  73. We use Array nodes only when we need to store more than 16 pointers
  74. in a single node.
  75. Array nodes do not store key objects or value objects. They are used
  76. only as an indirection level - their pointers point to other nodes in
  77. the tree.
  78. Bitmap Node
  79. -----------
  80. Allocating a new 32-pointers array for every node of our tree would be
  81. very expensive. Unless we store millions of keys, most of tree nodes would
  82. be very sparse.
  83. When we have less than 16 elements in a node, we don't want to use the
  84. Array node, that would mean that we waste a lot of memory. Instead,
  85. we can use bitmap compression and can have just as many pointers
  86. as we need!
  87. Bitmap nodes consist of two fields:
  88. 1. An array of pointers. If a Bitmap node holds N elements, the
  89. array will be of N pointers.
  90. 2. A 32bit integer -- a bitmap field. If an N-th bit is set in the
  91. bitmap, it means that the node has an N-th element.
  92. For example, say we need to store a 3 elements sparse array:
  93. +---+ -- +---+ -- +----+ -- +----+
  94. | 0 | .. | 4 | .. | 11 | .. | 17 |
  95. +---+ -- +---+ -- +----+ -- +----+
  96. | | |
  97. o1 o2 o3
  98. We allocate a three-pointer Bitmap node. Its bitmap field will be
  99. then set to:
  100. 0b_00100_00010_00000_10000 == (1 << 17) | (1 << 11) | (1 << 4)
  101. To check if our Bitmap node has an I-th element we can do:
  102. bitmap & (1 << I)
  103. And here's a formula to calculate a position in our pointer array
  104. which would correspond to an I-th element:
  105. popcount(bitmap & ((1 << I) - 1))
  106. Let's break it down:
  107. * `popcount` is a function that returns a number of bits set to 1;
  108. * `((1 << I) - 1)` is a mask to filter the bitmask to contain bits
  109. set to the *right* of our bit.
  110. So for our 17, 11, and 4 indexes:
  111. * bitmap & ((1 << 17) - 1) == 0b100000010000 => 2 bits are set => index is 2.
  112. * bitmap & ((1 << 11) - 1) == 0b10000 => 1 bit is set => index is 1.
  113. * bitmap & ((1 << 4) - 1) == 0b0 => 0 bits are set => index is 0.
  114. To conclude: Bitmap nodes are just like Array nodes -- they can store
  115. a number of pointers, but use bitmap compression to eliminate unused
  116. pointers.
  117. Bitmap nodes have two pointers for each item:
  118. +----+----+----+----+ -- +----+----+
  119. | k1 | v1 | k2 | v2 | .. | kN | vN |
  120. +----+----+----+----+ -- +----+----+
  121. When kI == NULL, vI points to another tree level.
  122. When kI != NULL, the actual key object is stored in kI, and its
  123. value is stored in vI.
  124. Collision Nodes
  125. ---------------
  126. Collision nodes are simple arrays of pointers -- two pointers per
  127. key/value. When there's a hash collision, say for k1/v1 and k2/v2
  128. we have `hash(k1)==hash(k2)`. Then our collision node will be:
  129. +----+----+----+----+
  130. | k1 | v1 | k2 | v2 |
  131. +----+----+----+----+
  132. Tree Structure
  133. --------------
  134. All nodes are PyObjects.
  135. The `MapObject` object has a pointer to the root node (h_root),
  136. and has a length field (h_count).
  137. High-level functions accept a MapObject object and dispatch to
  138. lower-level functions depending on what kind of node h_root points to.
  139. Operations
  140. ==========
  141. There are three fundamental operations on an immutable dictionary:
  142. 1. "o.assoc(k, v)" will return a new immutable dictionary, that will be
  143. a copy of "o", but with the "k/v" item set.
  144. Functions in this file:
  145. map_node_assoc, map_node_bitmap_assoc,
  146. map_node_array_assoc, map_node_collision_assoc
  147. `map_node_assoc` function accepts a node object, and calls
  148. other functions depending on its actual type.
  149. 2. "o.find(k)" will lookup key "k" in "o".
  150. Functions:
  151. map_node_find, map_node_bitmap_find,
  152. map_node_array_find, map_node_collision_find
  153. 3. "o.without(k)" will return a new immutable dictionary, that will be
  154. a copy of "o", buth without the "k" key.
  155. Functions:
  156. map_node_without, map_node_bitmap_without,
  157. map_node_array_without, map_node_collision_without
  158. Further Reading
  159. ===============
  160. 1. http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice.html
  161. 2. http://blog.higher-order.net/2010/08/16/assoc-and-clojures-persistenthashmap-part-ii.html
  162. 3. Clojure's PersistentHashMap implementation:
  163. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java
  164. */
  165. #define IS_ARRAY_NODE(node) (Py_TYPE(node) == &_Map_ArrayNode_Type)
  166. #define IS_BITMAP_NODE(node) (Py_TYPE(node) == &_Map_BitmapNode_Type)
  167. #define IS_COLLISION_NODE(node) (Py_TYPE(node) == &_Map_CollisionNode_Type)
  168. /* Return type for 'find' (lookup a key) functions.
  169. * F_ERROR - an error occurred;
  170. * F_NOT_FOUND - the key was not found;
  171. * F_FOUND - the key was found.
  172. */
  173. typedef enum {F_ERROR, F_NOT_FOUND, F_FOUND} map_find_t;
  174. /* Return type for 'without' (delete a key) functions.
  175. * W_ERROR - an error occurred;
  176. * W_NOT_FOUND - the key was not found: there's nothing to delete;
  177. * W_EMPTY - the key was found: the node/tree would be empty
  178. if the key is deleted;
  179. * W_NEWNODE - the key was found: a new node/tree is returned
  180. without that key.
  181. */
  182. typedef enum {W_ERROR, W_NOT_FOUND, W_EMPTY, W_NEWNODE} map_without_t;
  183. /* Low-level iterator protocol type.
  184. * I_ITEM - a new item has been yielded;
  185. * I_END - the whole tree was visited (similar to StopIteration).
  186. */
  187. typedef enum {I_ITEM, I_END} map_iter_t;
  188. #define HAMT_ARRAY_NODE_SIZE 32
  189. typedef struct {
  190. PyObject_HEAD
  191. MapNode *a_array[HAMT_ARRAY_NODE_SIZE];
  192. Py_ssize_t a_count;
  193. uint64_t a_mutid;
  194. } MapNode_Array;
  195. typedef struct {
  196. PyObject_VAR_HEAD
  197. uint64_t b_mutid;
  198. uint32_t b_bitmap;
  199. PyObject *b_array[1];
  200. } MapNode_Bitmap;
  201. typedef struct {
  202. PyObject_VAR_HEAD
  203. uint64_t c_mutid;
  204. int32_t c_hash;
  205. PyObject *c_array[1];
  206. } MapNode_Collision;
  207. static volatile uint64_t mutid_counter = 1;
  208. static MapNode_Bitmap *_empty_bitmap_node;
  209. /* Create a new HAMT immutable mapping. */
  210. static MapObject *
  211. map_new(void);
  212. /* Return a new collection based on "o", but with an additional
  213. key/val pair. */
  214. static MapObject *
  215. map_assoc(MapObject *o, PyObject *key, PyObject *val);
  216. /* Return a new collection based on "o", but without "key". */
  217. static MapObject *
  218. map_without(MapObject *o, PyObject *key);
  219. /* Check if "v" is equal to "w".
  220. Return:
  221. - 0: v != w
  222. - 1: v == w
  223. - -1: An error occurred.
  224. */
  225. static int
  226. map_eq(BaseMapObject *v, BaseMapObject *w);
  227. static map_find_t
  228. map_find(BaseMapObject *o, PyObject *key, PyObject **val);
  229. /* Return the size of "o"; equivalent of "len(o)". */
  230. static Py_ssize_t
  231. map_len(BaseMapObject *o);
  232. static MapObject *
  233. map_alloc(void);
  234. static MapNode *
  235. map_node_assoc(MapNode *node,
  236. uint32_t shift, int32_t hash,
  237. PyObject *key, PyObject *val, int* added_leaf,
  238. uint64_t mutid);
  239. static map_without_t
  240. map_node_without(MapNode *node,
  241. uint32_t shift, int32_t hash,
  242. PyObject *key,
  243. MapNode **new_node,
  244. uint64_t mutid);
  245. static map_find_t
  246. map_node_find(MapNode *node,
  247. uint32_t shift, int32_t hash,
  248. PyObject *key, PyObject **val);
  249. static int
  250. map_node_dump(MapNode *node,
  251. _PyUnicodeWriter *writer, int level);
  252. static MapNode *
  253. map_node_array_new(Py_ssize_t, uint64_t mutid);
  254. static MapNode *
  255. map_node_collision_new(int32_t hash, Py_ssize_t size, uint64_t mutid);
  256. static inline Py_ssize_t
  257. map_node_collision_count(MapNode_Collision *node);
  258. static int
  259. map_node_update(uint64_t mutid,
  260. PyObject *seq,
  261. MapNode *root, Py_ssize_t count,
  262. MapNode **new_root, Py_ssize_t *new_count);
  263. static int
  264. map_update_inplace(uint64_t mutid, BaseMapObject *o, PyObject *src);
  265. static MapObject *
  266. map_update(uint64_t mutid, MapObject *o, PyObject *src);
  267. #if !defined(NDEBUG)
  268. static void
  269. _map_node_array_validate(void *o)
  270. {
  271. assert(IS_ARRAY_NODE(o));
  272. MapNode_Array *node = (MapNode_Array*)(o);
  273. assert(node->a_count <= HAMT_ARRAY_NODE_SIZE);
  274. Py_ssize_t i = 0, count = 0;
  275. for (; i < HAMT_ARRAY_NODE_SIZE; i++) {
  276. if (node->a_array[i] != NULL) {
  277. count++;
  278. }
  279. }
  280. assert(count == node->a_count);
  281. }
  282. #define VALIDATE_ARRAY_NODE(NODE) \
  283. do { _map_node_array_validate(NODE); } while (0);
  284. #else
  285. #define VALIDATE_ARRAY_NODE(NODE)
  286. #endif
  287. /* Returns -1 on error */
  288. static inline int32_t
  289. map_hash(PyObject *o)
  290. {
  291. Py_hash_t hash = PyObject_Hash(o);
  292. #if SIZEOF_PY_HASH_T <= 4
  293. return hash;
  294. #else
  295. if (hash == -1) {
  296. /* exception */
  297. return -1;
  298. }
  299. /* While it's suboptimal to reduce Python's 64 bit hash to
  300. 32 bits via XOR, it seems that the resulting hash function
  301. is good enough (this is also how Long type is hashed in Java.)
  302. Storing 10, 100, 1000 Python strings results in a relatively
  303. shallow and uniform tree structure.
  304. Please don't change this hashing algorithm, as there are many
  305. tests that test some exact tree shape to cover all code paths.
  306. */
  307. int32_t xored = (int32_t)(hash & 0xffffffffl) ^ (int32_t)(hash >> 32);
  308. return xored == -1 ? -2 : xored;
  309. #endif
  310. }
  311. static inline uint32_t
  312. map_mask(int32_t hash, uint32_t shift)
  313. {
  314. return (((uint32_t)hash >> shift) & 0x01f);
  315. }
  316. static inline uint32_t
  317. map_bitpos(int32_t hash, uint32_t shift)
  318. {
  319. return (uint32_t)1 << map_mask(hash, shift);
  320. }
  321. static inline uint32_t
  322. map_bitcount(uint32_t i)
  323. {
  324. /* We could use native popcount instruction but that would
  325. require to either add configure flags to enable SSE4.2
  326. support or to detect it dynamically. Otherwise, we have
  327. a risk of CPython not working properly on older hardware.
  328. In practice, there's no observable difference in
  329. performance between using a popcount instruction or the
  330. following fallback code.
  331. The algorithm is copied from:
  332. https://graphics.stanford.edu/~seander/bithacks.html
  333. */
  334. i = i - ((i >> 1) & 0x55555555);
  335. i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
  336. return (((i + (i >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
  337. }
  338. static inline uint32_t
  339. map_bitindex(uint32_t bitmap, uint32_t bit)
  340. {
  341. return map_bitcount(bitmap & (bit - 1));
  342. }
  343. /////////////////////////////////// Dump Helpers
  344. static int
  345. _map_dump_ident(_PyUnicodeWriter *writer, int level)
  346. {
  347. /* Write `' ' * level` to the `writer` */
  348. PyObject *str = NULL;
  349. PyObject *num = NULL;
  350. PyObject *res = NULL;
  351. int ret = -1;
  352. str = PyUnicode_FromString(" ");
  353. if (str == NULL) {
  354. goto error;
  355. }
  356. num = PyLong_FromLong((long)level);
  357. if (num == NULL) {
  358. goto error;
  359. }
  360. res = PyNumber_Multiply(str, num);
  361. if (res == NULL) {
  362. goto error;
  363. }
  364. ret = _PyUnicodeWriter_WriteStr(writer, res);
  365. error:
  366. Py_XDECREF(res);
  367. Py_XDECREF(str);
  368. Py_XDECREF(num);
  369. return ret;
  370. }
  371. static int
  372. _map_dump_format(_PyUnicodeWriter *writer, const char *format, ...)
  373. {
  374. /* A convenient helper combining _PyUnicodeWriter_WriteStr and
  375. PyUnicode_FromFormatV.
  376. */
  377. PyObject* msg;
  378. int ret;
  379. va_list vargs;
  380. #ifdef HAVE_STDARG_PROTOTYPES
  381. va_start(vargs, format);
  382. #else
  383. va_start(vargs);
  384. #endif
  385. msg = PyUnicode_FromFormatV(format, vargs);
  386. va_end(vargs);
  387. if (msg == NULL) {
  388. return -1;
  389. }
  390. ret = _PyUnicodeWriter_WriteStr(writer, msg);
  391. Py_DECREF(msg);
  392. return ret;
  393. }
  394. /////////////////////////////////// Bitmap Node
  395. static MapNode *
  396. map_node_bitmap_new(Py_ssize_t size, uint64_t mutid)
  397. {
  398. /* Create a new bitmap node of size 'size' */
  399. MapNode_Bitmap *node;
  400. Py_ssize_t i;
  401. assert(size >= 0);
  402. assert(size % 2 == 0);
  403. if (size == 0 && _empty_bitmap_node != NULL && mutid == 0) {
  404. Py_INCREF(_empty_bitmap_node);
  405. return (MapNode *)_empty_bitmap_node;
  406. }
  407. /* No freelist; allocate a new bitmap node */
  408. node = PyObject_GC_NewVar(
  409. MapNode_Bitmap, &_Map_BitmapNode_Type, size);
  410. if (node == NULL) {
  411. return NULL;
  412. }
  413. Py_SET_SIZE(node, size);
  414. for (i = 0; i < size; i++) {
  415. node->b_array[i] = NULL;
  416. }
  417. node->b_bitmap = 0;
  418. node->b_mutid = mutid;
  419. PyObject_GC_Track(node);
  420. if (size == 0 && _empty_bitmap_node == NULL && mutid == 0) {
  421. /* Since bitmap nodes are immutable, we can cache the instance
  422. for size=0 and reuse it whenever we need an empty bitmap node.
  423. */
  424. _empty_bitmap_node = node;
  425. Py_INCREF(_empty_bitmap_node);
  426. }
  427. return (MapNode *)node;
  428. }
  429. static inline Py_ssize_t
  430. map_node_bitmap_count(MapNode_Bitmap *node)
  431. {
  432. return Py_SIZE(node) / 2;
  433. }
  434. static MapNode_Bitmap *
  435. map_node_bitmap_clone(MapNode_Bitmap *node, uint64_t mutid)
  436. {
  437. /* Clone a bitmap node; return a new one with the same child notes. */
  438. MapNode_Bitmap *clone;
  439. Py_ssize_t i;
  440. clone = (MapNode_Bitmap *)map_node_bitmap_new(
  441. Py_SIZE(node), mutid);
  442. if (clone == NULL) {
  443. return NULL;
  444. }
  445. for (i = 0; i < Py_SIZE(node); i++) {
  446. Py_XINCREF(node->b_array[i]);
  447. clone->b_array[i] = node->b_array[i];
  448. }
  449. clone->b_bitmap = node->b_bitmap;
  450. return clone;
  451. }
  452. static MapNode_Bitmap *
  453. map_node_bitmap_clone_without(MapNode_Bitmap *o, uint32_t bit, uint64_t mutid)
  454. {
  455. assert(bit & o->b_bitmap);
  456. assert(map_node_bitmap_count(o) > 1);
  457. MapNode_Bitmap *new = (MapNode_Bitmap *)map_node_bitmap_new(
  458. Py_SIZE(o) - 2, mutid);
  459. if (new == NULL) {
  460. return NULL;
  461. }
  462. uint32_t idx = map_bitindex(o->b_bitmap, bit);
  463. uint32_t key_idx = 2 * idx;
  464. uint32_t val_idx = key_idx + 1;
  465. uint32_t i;
  466. for (i = 0; i < key_idx; i++) {
  467. Py_XINCREF(o->b_array[i]);
  468. new->b_array[i] = o->b_array[i];
  469. }
  470. assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32);
  471. for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) {
  472. Py_XINCREF(o->b_array[i]);
  473. new->b_array[i - 2] = o->b_array[i];
  474. }
  475. new->b_bitmap = o->b_bitmap & ~bit;
  476. return new;
  477. }
  478. static MapNode *
  479. map_node_new_bitmap_or_collision(uint32_t shift,
  480. PyObject *key1, PyObject *val1,
  481. int32_t key2_hash,
  482. PyObject *key2, PyObject *val2,
  483. uint64_t mutid)
  484. {
  485. /* Helper method. Creates a new node for key1/val and key2/val2
  486. pairs.
  487. If key1 hash is equal to the hash of key2, a Collision node
  488. will be created. If they are not equal, a Bitmap node is
  489. created.
  490. */
  491. int32_t key1_hash = map_hash(key1);
  492. if (key1_hash == -1) {
  493. return NULL;
  494. }
  495. if (key1_hash == key2_hash) {
  496. MapNode_Collision *n;
  497. n = (MapNode_Collision *)map_node_collision_new(key1_hash, 4, mutid);
  498. if (n == NULL) {
  499. return NULL;
  500. }
  501. Py_INCREF(key1);
  502. n->c_array[0] = key1;
  503. Py_INCREF(val1);
  504. n->c_array[1] = val1;
  505. Py_INCREF(key2);
  506. n->c_array[2] = key2;
  507. Py_INCREF(val2);
  508. n->c_array[3] = val2;
  509. return (MapNode *)n;
  510. }
  511. else {
  512. int added_leaf = 0;
  513. MapNode *n = map_node_bitmap_new(0, mutid);
  514. if (n == NULL) {
  515. return NULL;
  516. }
  517. MapNode *n2 = map_node_assoc(
  518. n, shift, key1_hash, key1, val1, &added_leaf, mutid);
  519. Py_DECREF(n);
  520. if (n2 == NULL) {
  521. return NULL;
  522. }
  523. n = map_node_assoc(
  524. n2, shift, key2_hash, key2, val2, &added_leaf, mutid);
  525. Py_DECREF(n2);
  526. if (n == NULL) {
  527. return NULL;
  528. }
  529. return n;
  530. }
  531. }
  532. static MapNode *
  533. map_node_bitmap_assoc(MapNode_Bitmap *self,
  534. uint32_t shift, int32_t hash,
  535. PyObject *key, PyObject *val, int* added_leaf,
  536. uint64_t mutid)
  537. {
  538. /* assoc operation for bitmap nodes.
  539. Return: a new node, or self if key/val already is in the
  540. collection.
  541. 'added_leaf' is later used in 'map_assoc' to determine if
  542. `map.set(key, val)` increased the size of the collection.
  543. */
  544. uint32_t bit = map_bitpos(hash, shift);
  545. uint32_t idx = map_bitindex(self->b_bitmap, bit);
  546. /* Bitmap node layout:
  547. +------+------+------+------+ --- +------+------+
  548. | key1 | val1 | key2 | val2 | ... | keyN | valN |
  549. +------+------+------+------+ --- +------+------+
  550. where `N < Py_SIZE(node)`.
  551. The `node->b_bitmap` field is a bitmap. For a given
  552. `(shift, hash)` pair we can determine:
  553. - If this node has the corresponding key/val slots.
  554. - The index of key/val slots.
  555. */
  556. if (self->b_bitmap & bit) {
  557. /* The key is set in this node */
  558. uint32_t key_idx = 2 * idx;
  559. uint32_t val_idx = key_idx + 1;
  560. assert(val_idx < (size_t)Py_SIZE(self));
  561. PyObject *key_or_null = self->b_array[key_idx];
  562. PyObject *val_or_node = self->b_array[val_idx];
  563. if (key_or_null == NULL) {
  564. /* key is NULL. This means that we have a few keys
  565. that have the same (hash, shift) pair. */
  566. assert(val_or_node != NULL);
  567. MapNode *sub_node = map_node_assoc(
  568. (MapNode *)val_or_node,
  569. shift + 5, hash, key, val, added_leaf,
  570. mutid);
  571. if (sub_node == NULL) {
  572. return NULL;
  573. }
  574. if (val_or_node == (PyObject *)sub_node) {
  575. Py_DECREF(sub_node);
  576. Py_INCREF(self);
  577. return (MapNode *)self;
  578. }
  579. if (mutid != 0 && self->b_mutid == mutid) {
  580. Py_SETREF(self->b_array[val_idx], (PyObject*)sub_node);
  581. Py_INCREF(self);
  582. return (MapNode *)self;
  583. }
  584. else {
  585. MapNode_Bitmap *ret = map_node_bitmap_clone(self, mutid);
  586. if (ret == NULL) {
  587. return NULL;
  588. }
  589. Py_SETREF(ret->b_array[val_idx], (PyObject*)sub_node);
  590. return (MapNode *)ret;
  591. }
  592. }
  593. assert(key != NULL);
  594. /* key is not NULL. This means that we have only one other
  595. key in this collection that matches our hash for this shift. */
  596. int comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ);
  597. if (comp_err < 0) { /* exception in __eq__ */
  598. return NULL;
  599. }
  600. if (comp_err == 1) { /* key == key_or_null */
  601. if (val == val_or_node) {
  602. /* we already have the same key/val pair; return self. */
  603. Py_INCREF(self);
  604. return (MapNode *)self;
  605. }
  606. /* We're setting a new value for the key we had before. */
  607. if (mutid != 0 && self->b_mutid == mutid) {
  608. /* We've been mutating this node before: update inplace. */
  609. Py_INCREF(val);
  610. Py_SETREF(self->b_array[val_idx], val);
  611. Py_INCREF(self);
  612. return (MapNode *)self;
  613. }
  614. else {
  615. /* Make a new bitmap node with a replaced value,
  616. and return it. */
  617. MapNode_Bitmap *ret = map_node_bitmap_clone(self, mutid);
  618. if (ret == NULL) {
  619. return NULL;
  620. }
  621. Py_INCREF(val);
  622. Py_SETREF(ret->b_array[val_idx], val);
  623. return (MapNode *)ret;
  624. }
  625. }
  626. /* It's a new key, and it has the same index as *one* another key.
  627. We have a collision. We need to create a new node which will
  628. combine the existing key and the key we're adding.
  629. `map_node_new_bitmap_or_collision` will either create a new
  630. Collision node if the keys have identical hashes, or
  631. a new Bitmap node.
  632. */
  633. MapNode *sub_node = map_node_new_bitmap_or_collision(
  634. shift + 5,
  635. key_or_null, val_or_node, /* existing key/val */
  636. hash,
  637. key, val, /* new key/val */
  638. self->b_mutid
  639. );
  640. if (sub_node == NULL) {
  641. return NULL;
  642. }
  643. if (mutid != 0 && self->b_mutid == mutid) {
  644. Py_SETREF(self->b_array[key_idx], NULL);
  645. Py_SETREF(self->b_array[val_idx], (PyObject *)sub_node);
  646. Py_INCREF(self);
  647. *added_leaf = 1;
  648. return (MapNode *)self;
  649. }
  650. else {
  651. MapNode_Bitmap *ret = map_node_bitmap_clone(self, mutid);
  652. if (ret == NULL) {
  653. Py_DECREF(sub_node);
  654. return NULL;
  655. }
  656. Py_SETREF(ret->b_array[key_idx], NULL);
  657. Py_SETREF(ret->b_array[val_idx], (PyObject *)sub_node);
  658. *added_leaf = 1;
  659. return (MapNode *)ret;
  660. }
  661. }
  662. else {
  663. /* There was no key before with the same (shift,hash). */
  664. uint32_t n = map_bitcount(self->b_bitmap);
  665. if (n >= 16) {
  666. /* When we have a situation where we want to store more
  667. than 16 nodes at one level of the tree, we no longer
  668. want to use the Bitmap node with bitmap encoding.
  669. Instead we start using an Array node, which has
  670. simpler (faster) implementation at the expense of
  671. having prealocated 32 pointers for its keys/values
  672. pairs.
  673. Small map objects (<30 keys) usually don't have any
  674. Array nodes at all. Between ~30 and ~400 keys map
  675. objects usually have one Array node, and usually it's
  676. a root node.
  677. */
  678. uint32_t jdx = map_mask(hash, shift);
  679. /* 'jdx' is the index of where the new key should be added
  680. in the new Array node we're about to create. */
  681. MapNode *empty = NULL;
  682. MapNode_Array *new_node = NULL;
  683. MapNode *res = NULL;
  684. /* Create a new Array node. */
  685. new_node = (MapNode_Array *)map_node_array_new(n + 1, mutid);
  686. if (new_node == NULL) {
  687. goto fin;
  688. }
  689. /* Create an empty bitmap node for the next
  690. map_node_assoc call. */
  691. empty = map_node_bitmap_new(0, mutid);
  692. if (empty == NULL) {
  693. goto fin;
  694. }
  695. /* Make a new bitmap node for the key/val we're adding.
  696. Set that bitmap node to new-array-node[jdx]. */
  697. new_node->a_array[jdx] = map_node_assoc(
  698. empty, shift + 5, hash, key, val, added_leaf, mutid);
  699. if (new_node->a_array[jdx] == NULL) {
  700. goto fin;
  701. }
  702. /* Copy existing key/value pairs from the current Bitmap
  703. node to the new Array node we've just created. */
  704. Py_ssize_t i, j;
  705. for (i = 0, j = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  706. if (((self->b_bitmap >> i) & 1) != 0) {
  707. /* Ensure we don't accidentally override `jdx` element
  708. we set few lines above.
  709. */
  710. assert(new_node->a_array[i] == NULL);
  711. if (self->b_array[j] == NULL) {
  712. new_node->a_array[i] =
  713. (MapNode *)self->b_array[j + 1];
  714. Py_INCREF(new_node->a_array[i]);
  715. }
  716. else {
  717. int32_t rehash = map_hash(self->b_array[j]);
  718. if (rehash == -1) {
  719. goto fin;
  720. }
  721. new_node->a_array[i] = map_node_assoc(
  722. empty, shift + 5,
  723. rehash,
  724. self->b_array[j],
  725. self->b_array[j + 1],
  726. added_leaf,
  727. mutid);
  728. if (new_node->a_array[i] == NULL) {
  729. goto fin;
  730. }
  731. }
  732. j += 2;
  733. }
  734. }
  735. VALIDATE_ARRAY_NODE(new_node)
  736. /* That's it! */
  737. res = (MapNode *)new_node;
  738. fin:
  739. Py_XDECREF(empty);
  740. if (res == NULL) {
  741. Py_XDECREF(new_node);
  742. }
  743. return res;
  744. }
  745. else {
  746. /* We have less than 16 keys at this level; let's just
  747. create a new bitmap node out of this node with the
  748. new key/val pair added. */
  749. uint32_t key_idx = 2 * idx;
  750. uint32_t val_idx = key_idx + 1;
  751. uint32_t i;
  752. *added_leaf = 1;
  753. /* Allocate new Bitmap node which can have one more key/val
  754. pair in addition to what we have already. */
  755. MapNode_Bitmap *new_node =
  756. (MapNode_Bitmap *)map_node_bitmap_new(2 * (n + 1), mutid);
  757. if (new_node == NULL) {
  758. return NULL;
  759. }
  760. /* Copy all keys/values that will be before the new key/value
  761. we are adding. */
  762. for (i = 0; i < key_idx; i++) {
  763. Py_XINCREF(self->b_array[i]);
  764. new_node->b_array[i] = self->b_array[i];
  765. }
  766. /* Set the new key/value to the new Bitmap node. */
  767. Py_INCREF(key);
  768. new_node->b_array[key_idx] = key;
  769. Py_INCREF(val);
  770. new_node->b_array[val_idx] = val;
  771. /* Copy all keys/values that will be after the new key/value
  772. we are adding. */
  773. assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32);
  774. for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) {
  775. Py_XINCREF(self->b_array[i]);
  776. new_node->b_array[i + 2] = self->b_array[i];
  777. }
  778. new_node->b_bitmap = self->b_bitmap | bit;
  779. return (MapNode *)new_node;
  780. }
  781. }
  782. }
  783. static map_without_t
  784. map_node_bitmap_without(MapNode_Bitmap *self,
  785. uint32_t shift, int32_t hash,
  786. PyObject *key,
  787. MapNode **new_node,
  788. uint64_t mutid)
  789. {
  790. uint32_t bit = map_bitpos(hash, shift);
  791. if ((self->b_bitmap & bit) == 0) {
  792. return W_NOT_FOUND;
  793. }
  794. uint32_t idx = map_bitindex(self->b_bitmap, bit);
  795. uint32_t key_idx = 2 * idx;
  796. uint32_t val_idx = key_idx + 1;
  797. PyObject *key_or_null = self->b_array[key_idx];
  798. PyObject *val_or_node = self->b_array[val_idx];
  799. if (key_or_null == NULL) {
  800. /* key == NULL means that 'value' is another tree node. */
  801. MapNode *sub_node = NULL;
  802. MapNode_Bitmap *target = NULL;
  803. map_without_t res = map_node_without(
  804. (MapNode *)val_or_node,
  805. shift + 5, hash, key, &sub_node,
  806. mutid);
  807. switch (res) {
  808. case W_EMPTY:
  809. /* It's impossible for us to receive a W_EMPTY here:
  810. - Array nodes are converted to Bitmap nodes when
  811. we delete 16th item from them;
  812. - Collision nodes are converted to Bitmap when
  813. there is one item in them;
  814. - Bitmap node's without() inlines single-item
  815. sub-nodes.
  816. So in no situation we can have a single-item
  817. Bitmap child of another Bitmap node.
  818. */
  819. abort();
  820. case W_NEWNODE: {
  821. assert(sub_node != NULL);
  822. if (IS_BITMAP_NODE(sub_node)) {
  823. MapNode_Bitmap *sub_tree = (MapNode_Bitmap *)sub_node;
  824. if (map_node_bitmap_count(sub_tree) == 1 &&
  825. sub_tree->b_array[0] != NULL)
  826. {
  827. /* A bitmap node with one key/value pair. Just
  828. merge it into this node.
  829. Note that we don't inline Bitmap nodes that
  830. have a NULL key -- those nodes point to another
  831. tree level, and we cannot simply move tree levels
  832. up or down.
  833. */
  834. if (mutid != 0 && self->b_mutid == mutid) {
  835. target = self;
  836. Py_INCREF(target);
  837. }
  838. else {
  839. target = map_node_bitmap_clone(self, mutid);
  840. if (target == NULL) {
  841. Py_DECREF(sub_node);
  842. return W_ERROR;
  843. }
  844. }
  845. PyObject *key = sub_tree->b_array[0];
  846. PyObject *val = sub_tree->b_array[1];
  847. Py_INCREF(key);
  848. Py_XSETREF(target->b_array[key_idx], key);
  849. Py_INCREF(val);
  850. Py_SETREF(target->b_array[val_idx], val);
  851. Py_DECREF(sub_tree);
  852. *new_node = (MapNode *)target;
  853. return W_NEWNODE;
  854. }
  855. }
  856. #if !defined(NDEBUG)
  857. /* Ensure that Collision.without implementation
  858. converts to Bitmap nodes itself.
  859. */
  860. if (IS_COLLISION_NODE(sub_node)) {
  861. assert(map_node_collision_count(
  862. (MapNode_Collision*)sub_node) > 1);
  863. }
  864. #endif
  865. if (mutid != 0 && self->b_mutid == mutid) {
  866. target = self;
  867. Py_INCREF(target);
  868. }
  869. else {
  870. target = map_node_bitmap_clone(self, mutid);
  871. if (target == NULL) {
  872. return W_ERROR;
  873. }
  874. }
  875. Py_SETREF(target->b_array[val_idx],
  876. (PyObject *)sub_node); /* borrow */
  877. *new_node = (MapNode *)target;
  878. return W_NEWNODE;
  879. }
  880. case W_ERROR:
  881. case W_NOT_FOUND:
  882. assert(sub_node == NULL);
  883. return res;
  884. default:
  885. abort();
  886. }
  887. }
  888. else {
  889. /* We have a regular key/value pair */
  890. int cmp = PyObject_RichCompareBool(key_or_null, key, Py_EQ);
  891. if (cmp < 0) {
  892. return W_ERROR;
  893. }
  894. if (cmp == 0) {
  895. return W_NOT_FOUND;
  896. }
  897. if (map_node_bitmap_count(self) == 1) {
  898. return W_EMPTY;
  899. }
  900. *new_node = (MapNode *)
  901. map_node_bitmap_clone_without(self, bit, mutid);
  902. if (*new_node == NULL) {
  903. return W_ERROR;
  904. }
  905. return W_NEWNODE;
  906. }
  907. }
  908. static map_find_t
  909. map_node_bitmap_find(MapNode_Bitmap *self,
  910. uint32_t shift, int32_t hash,
  911. PyObject *key, PyObject **val)
  912. {
  913. /* Lookup a key in a Bitmap node. */
  914. uint32_t bit = map_bitpos(hash, shift);
  915. uint32_t idx;
  916. uint32_t key_idx;
  917. uint32_t val_idx;
  918. PyObject *key_or_null;
  919. PyObject *val_or_node;
  920. int comp_err;
  921. if ((self->b_bitmap & bit) == 0) {
  922. return F_NOT_FOUND;
  923. }
  924. idx = map_bitindex(self->b_bitmap, bit);
  925. key_idx = idx * 2;
  926. val_idx = key_idx + 1;
  927. assert(val_idx < (size_t)Py_SIZE(self));
  928. key_or_null = self->b_array[key_idx];
  929. val_or_node = self->b_array[val_idx];
  930. if (key_or_null == NULL) {
  931. /* There are a few keys that have the same hash at the current shift
  932. that match our key. Dispatch the lookup further down the tree. */
  933. assert(val_or_node != NULL);
  934. return map_node_find((MapNode *)val_or_node,
  935. shift + 5, hash, key, val);
  936. }
  937. /* We have only one key -- a potential match. Let's compare if the
  938. key we are looking at is equal to the key we are looking for. */
  939. assert(key != NULL);
  940. comp_err = PyObject_RichCompareBool(key, key_or_null, Py_EQ);
  941. if (comp_err < 0) { /* exception in __eq__ */
  942. return F_ERROR;
  943. }
  944. if (comp_err == 1) { /* key == key_or_null */
  945. *val = val_or_node;
  946. return F_FOUND;
  947. }
  948. return F_NOT_FOUND;
  949. }
  950. static int
  951. map_node_bitmap_traverse(MapNode_Bitmap *self, visitproc visit, void *arg)
  952. {
  953. /* Bitmap's tp_traverse */
  954. Py_ssize_t i;
  955. for (i = Py_SIZE(self); --i >= 0; ) {
  956. Py_VISIT(self->b_array[i]);
  957. }
  958. return 0;
  959. }
  960. static void
  961. map_node_bitmap_dealloc(MapNode_Bitmap *self)
  962. {
  963. /* Bitmap's tp_dealloc */
  964. Py_ssize_t len = Py_SIZE(self);
  965. Py_ssize_t i;
  966. PyObject_GC_UnTrack(self);
  967. Py_TRASHCAN_SAFE_BEGIN(self)
  968. if (len > 0) {
  969. i = len;
  970. while (--i >= 0) {
  971. Py_XDECREF(self->b_array[i]);
  972. }
  973. }
  974. Py_TYPE(self)->tp_free((PyObject *)self);
  975. Py_TRASHCAN_SAFE_END(self)
  976. }
  977. static int
  978. map_node_bitmap_dump(MapNode_Bitmap *node,
  979. _PyUnicodeWriter *writer, int level)
  980. {
  981. /* Debug build: __dump__() method implementation for Bitmap nodes. */
  982. Py_ssize_t i;
  983. PyObject *tmp1;
  984. PyObject *tmp2;
  985. if (_map_dump_ident(writer, level + 1)) {
  986. goto error;
  987. }
  988. if (_map_dump_format(writer, "BitmapNode(size=%zd count=%zd ",
  989. Py_SIZE(node), Py_SIZE(node) / 2))
  990. {
  991. goto error;
  992. }
  993. tmp1 = PyLong_FromUnsignedLong(node->b_bitmap);
  994. if (tmp1 == NULL) {
  995. goto error;
  996. }
  997. tmp2 = _PyLong_Format(tmp1, 2);
  998. Py_DECREF(tmp1);
  999. if (tmp2 == NULL) {
  1000. goto error;
  1001. }
  1002. if (_map_dump_format(writer, "bitmap=%S id=%p):\n", tmp2, node)) {
  1003. Py_DECREF(tmp2);
  1004. goto error;
  1005. }
  1006. Py_DECREF(tmp2);
  1007. for (i = 0; i < Py_SIZE(node); i += 2) {
  1008. PyObject *key_or_null = node->b_array[i];
  1009. PyObject *val_or_node = node->b_array[i + 1];
  1010. if (_map_dump_ident(writer, level + 2)) {
  1011. goto error;
  1012. }
  1013. if (key_or_null == NULL) {
  1014. if (_map_dump_format(writer, "NULL:\n")) {
  1015. goto error;
  1016. }
  1017. if (map_node_dump((MapNode *)val_or_node,
  1018. writer, level + 2))
  1019. {
  1020. goto error;
  1021. }
  1022. }
  1023. else {
  1024. if (_map_dump_format(writer, "%R: %R", key_or_null,
  1025. val_or_node))
  1026. {
  1027. goto error;
  1028. }
  1029. }
  1030. if (_map_dump_format(writer, "\n")) {
  1031. goto error;
  1032. }
  1033. }
  1034. return 0;
  1035. error:
  1036. return -1;
  1037. }
  1038. /////////////////////////////////// Collision Node
  1039. static MapNode *
  1040. map_node_collision_new(int32_t hash, Py_ssize_t size, uint64_t mutid)
  1041. {
  1042. /* Create a new Collision node. */
  1043. MapNode_Collision *node;
  1044. Py_ssize_t i;
  1045. assert(size >= 4);
  1046. assert(size % 2 == 0);
  1047. node = PyObject_GC_NewVar(
  1048. MapNode_Collision, &_Map_CollisionNode_Type, size);
  1049. if (node == NULL) {
  1050. return NULL;
  1051. }
  1052. for (i = 0; i < size; i++) {
  1053. node->c_array[i] = NULL;
  1054. }
  1055. Py_SET_SIZE(node, size);
  1056. node->c_hash = hash;
  1057. node->c_mutid = mutid;
  1058. PyObject_GC_Track(node);
  1059. return (MapNode *)node;
  1060. }
  1061. static map_find_t
  1062. map_node_collision_find_index(MapNode_Collision *self, PyObject *key,
  1063. Py_ssize_t *idx)
  1064. {
  1065. /* Lookup `key` in the Collision node `self`. Set the index of the
  1066. found key to 'idx'. */
  1067. Py_ssize_t i;
  1068. PyObject *el;
  1069. for (i = 0; i < Py_SIZE(self); i += 2) {
  1070. el = self->c_array[i];
  1071. assert(el != NULL);
  1072. int cmp = PyObject_RichCompareBool(key, el, Py_EQ);
  1073. if (cmp < 0) {
  1074. return F_ERROR;
  1075. }
  1076. if (cmp == 1) {
  1077. *idx = i;
  1078. return F_FOUND;
  1079. }
  1080. }
  1081. return F_NOT_FOUND;
  1082. }
  1083. static MapNode *
  1084. map_node_collision_assoc(MapNode_Collision *self,
  1085. uint32_t shift, int32_t hash,
  1086. PyObject *key, PyObject *val, int* added_leaf,
  1087. uint64_t mutid)
  1088. {
  1089. /* Set a new key to this level (currently a Collision node)
  1090. of the tree. */
  1091. if (hash == self->c_hash) {
  1092. /* The hash of the 'key' we are adding matches the hash of
  1093. other keys in this Collision node. */
  1094. Py_ssize_t key_idx = -1;
  1095. map_find_t found;
  1096. MapNode_Collision *new_node;
  1097. Py_ssize_t i;
  1098. /* Let's try to lookup the new 'key', maybe we already have it. */
  1099. found = map_node_collision_find_index(self, key, &key_idx);
  1100. switch (found) {
  1101. case F_ERROR:
  1102. /* Exception. */
  1103. return NULL;
  1104. case F_NOT_FOUND:
  1105. /* This is a totally new key. Clone the current node,
  1106. add a new key/value to the cloned node. */
  1107. new_node = (MapNode_Collision *)map_node_collision_new(
  1108. self->c_hash, Py_SIZE(self) + 2, mutid);
  1109. if (new_node == NULL) {
  1110. return NULL;
  1111. }
  1112. for (i = 0; i < Py_SIZE(self); i++) {
  1113. Py_INCREF(self->c_array[i]);
  1114. new_node->c_array[i] = self->c_array[i];
  1115. }
  1116. Py_INCREF(key);
  1117. new_node->c_array[i] = key;
  1118. Py_INCREF(val);
  1119. new_node->c_array[i + 1] = val;
  1120. *added_leaf = 1;
  1121. return (MapNode *)new_node;
  1122. case F_FOUND:
  1123. /* There's a key which is equal to the key we are adding. */
  1124. assert(key_idx >= 0);
  1125. assert(key_idx < Py_SIZE(self));
  1126. Py_ssize_t val_idx = key_idx + 1;
  1127. if (self->c_array[val_idx] == val) {
  1128. /* We're setting a key/value pair that's already set. */
  1129. Py_INCREF(self);
  1130. return (MapNode *)self;
  1131. }
  1132. /* We need to replace old value for the key with
  1133. a new value. */
  1134. if (mutid != 0 && self->c_mutid == mutid) {
  1135. new_node = self;
  1136. Py_INCREF(self);
  1137. }
  1138. else {
  1139. /* Create a new Collision node.*/
  1140. new_node = (MapNode_Collision *)map_node_collision_new(
  1141. self->c_hash, Py_SIZE(self), mutid);
  1142. if (new_node == NULL) {
  1143. return NULL;
  1144. }
  1145. /* Copy all elements of the old node to the new one. */
  1146. for (i = 0; i < Py_SIZE(self); i++) {
  1147. Py_INCREF(self->c_array[i]);
  1148. new_node->c_array[i] = self->c_array[i];
  1149. }
  1150. }
  1151. /* Replace the old value with the new value for the our key. */
  1152. Py_DECREF(new_node->c_array[val_idx]);
  1153. Py_INCREF(val);
  1154. new_node->c_array[val_idx] = val;
  1155. return (MapNode *)new_node;
  1156. default:
  1157. abort();
  1158. }
  1159. }
  1160. else {
  1161. /* The hash of the new key is different from the hash that
  1162. all keys of this Collision node have.
  1163. Create a Bitmap node inplace with two children:
  1164. key/value pair that we're adding, and the Collision node
  1165. we're replacing on this tree level.
  1166. */
  1167. MapNode_Bitmap *new_node;
  1168. MapNode *assoc_res;
  1169. new_node = (MapNode_Bitmap *)map_node_bitmap_new(2, mutid);
  1170. if (new_node == NULL) {
  1171. return NULL;
  1172. }
  1173. new_node->b_bitmap = map_bitpos(self->c_hash, shift);
  1174. Py_INCREF(self);
  1175. new_node->b_array[1] = (PyObject*) self;
  1176. assoc_res = map_node_bitmap_assoc(
  1177. new_node, shift, hash, key, val, added_leaf, mutid);
  1178. Py_DECREF(new_node);
  1179. return assoc_res;
  1180. }
  1181. }
  1182. static inline Py_ssize_t
  1183. map_node_collision_count(MapNode_Collision *node)
  1184. {
  1185. return Py_SIZE(node) / 2;
  1186. }
  1187. static map_without_t
  1188. map_node_collision_without(MapNode_Collision *self,
  1189. uint32_t shift, int32_t hash,
  1190. PyObject *key,
  1191. MapNode **new_node,
  1192. uint64_t mutid)
  1193. {
  1194. if (hash != self->c_hash) {
  1195. return W_NOT_FOUND;
  1196. }
  1197. Py_ssize_t key_idx = -1;
  1198. map_find_t found = map_node_collision_find_index(self, key, &key_idx);
  1199. switch (found) {
  1200. case F_ERROR:
  1201. return W_ERROR;
  1202. case F_NOT_FOUND:
  1203. return W_NOT_FOUND;
  1204. case F_FOUND:
  1205. assert(key_idx >= 0);
  1206. assert(key_idx < Py_SIZE(self));
  1207. Py_ssize_t new_count = map_node_collision_count(self) - 1;
  1208. if (new_count == 0) {
  1209. /* The node has only one key/value pair and it's for the
  1210. key we're trying to delete. So a new node will be empty
  1211. after the removal.
  1212. */
  1213. return W_EMPTY;
  1214. }
  1215. if (new_count == 1) {
  1216. /* The node has two keys, and after deletion the
  1217. new Collision node would have one. Collision nodes
  1218. with one key shouldn't exist, so convert it to a
  1219. Bitmap node.
  1220. */
  1221. MapNode_Bitmap *node = (MapNode_Bitmap *)
  1222. map_node_bitmap_new(2, mutid);
  1223. if (node == NULL) {
  1224. return W_ERROR;
  1225. }
  1226. if (key_idx == 0) {
  1227. Py_INCREF(self->c_array[2]);
  1228. node->b_array[0] = self->c_array[2];
  1229. Py_INCREF(self->c_array[3]);
  1230. node->b_array[1] = self->c_array[3];
  1231. }
  1232. else {
  1233. assert(key_idx == 2);
  1234. Py_INCREF(self->c_array[0]);
  1235. node->b_array[0] = self->c_array[0];
  1236. Py_INCREF(self->c_array[1]);
  1237. node->b_array[1] = self->c_array[1];
  1238. }
  1239. node->b_bitmap = map_bitpos(hash, shift);
  1240. *new_node = (MapNode *)node;
  1241. return W_NEWNODE;
  1242. }
  1243. /* Allocate a new Collision node with capacity for one
  1244. less key/value pair */
  1245. MapNode_Collision *new = (MapNode_Collision *)
  1246. map_node_collision_new(
  1247. self->c_hash, Py_SIZE(self) - 2, mutid);
  1248. if (new == NULL) {
  1249. return W_ERROR;
  1250. }
  1251. /* Copy all other keys from `self` to `new` */
  1252. Py_ssize_t i;
  1253. for (i = 0; i < key_idx; i++) {
  1254. Py_INCREF(self->c_array[i]);
  1255. new->c_array[i] = self->c_array[i];
  1256. }
  1257. for (i = key_idx + 2; i < Py_SIZE(self); i++) {
  1258. Py_INCREF(self->c_array[i]);
  1259. new->c_array[i - 2] = self->c_array[i];
  1260. }
  1261. *new_node = (MapNode*)new;
  1262. return W_NEWNODE;
  1263. default:
  1264. abort();
  1265. }
  1266. }
  1267. static map_find_t
  1268. map_node_collision_find(MapNode_Collision *self,
  1269. uint32_t shift, int32_t hash,
  1270. PyObject *key, PyObject **val)
  1271. {
  1272. /* Lookup `key` in the Collision node `self`. Set the value
  1273. for the found key to 'val'. */
  1274. Py_ssize_t idx = -1;
  1275. map_find_t res;
  1276. res = map_node_collision_find_index(self, key, &idx);
  1277. if (res == F_ERROR || res == F_NOT_FOUND) {
  1278. return res;
  1279. }
  1280. assert(idx >= 0);
  1281. assert(idx + 1 < Py_SIZE(self));
  1282. *val = self->c_array[idx + 1];
  1283. assert(*val != NULL);
  1284. return F_FOUND;
  1285. }
  1286. static int
  1287. map_node_collision_traverse(MapNode_Collision *self,
  1288. visitproc visit, void *arg)
  1289. {
  1290. /* Collision's tp_traverse */
  1291. Py_ssize_t i;
  1292. for (i = Py_SIZE(self); --i >= 0; ) {
  1293. Py_VISIT(self->c_array[i]);
  1294. }
  1295. return 0;
  1296. }
  1297. static void
  1298. map_node_collision_dealloc(MapNode_Collision *self)
  1299. {
  1300. /* Collision's tp_dealloc */
  1301. Py_ssize_t len = Py_SIZE(self);
  1302. PyObject_GC_UnTrack(self);
  1303. Py_TRASHCAN_SAFE_BEGIN(self)
  1304. if (len > 0) {
  1305. while (--len >= 0) {
  1306. Py_XDECREF(self->c_array[len]);
  1307. }
  1308. }
  1309. Py_TYPE(self)->tp_free((PyObject *)self);
  1310. Py_TRASHCAN_SAFE_END(self)
  1311. }
  1312. static int
  1313. map_node_collision_dump(MapNode_Collision *node,
  1314. _PyUnicodeWriter *writer, int level)
  1315. {
  1316. /* Debug build: __dump__() method implementation for Collision nodes. */
  1317. Py_ssize_t i;
  1318. if (_map_dump_ident(writer, level + 1)) {
  1319. goto error;
  1320. }
  1321. if (_map_dump_format(writer, "CollisionNode(size=%zd id=%p):\n",
  1322. Py_SIZE(node), node))
  1323. {
  1324. goto error;
  1325. }
  1326. for (i = 0; i < Py_SIZE(node); i += 2) {
  1327. PyObject *key = node->c_array[i];
  1328. PyObject *val = node->c_array[i + 1];
  1329. if (_map_dump_ident(writer, level + 2)) {
  1330. goto error;
  1331. }
  1332. if (_map_dump_format(writer, "%R: %R\n", key, val)) {
  1333. goto error;
  1334. }
  1335. }
  1336. return 0;
  1337. error:
  1338. return -1;
  1339. }
  1340. /////////////////////////////////// Array Node
  1341. static MapNode *
  1342. map_node_array_new(Py_ssize_t count, uint64_t mutid)
  1343. {
  1344. Py_ssize_t i;
  1345. MapNode_Array *node = PyObject_GC_New(
  1346. MapNode_Array, &_Map_ArrayNode_Type);
  1347. if (node == NULL) {
  1348. return NULL;
  1349. }
  1350. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1351. node->a_array[i] = NULL;
  1352. }
  1353. node->a_count = count;
  1354. node->a_mutid = mutid;
  1355. PyObject_GC_Track(node);
  1356. return (MapNode *)node;
  1357. }
  1358. static MapNode_Array *
  1359. map_node_array_clone(MapNode_Array *node, uint64_t mutid)
  1360. {
  1361. MapNode_Array *clone;
  1362. Py_ssize_t i;
  1363. VALIDATE_ARRAY_NODE(node)
  1364. assert(node->a_count <= HAMT_ARRAY_NODE_SIZE);
  1365. /* Create a new Array node. */
  1366. clone = (MapNode_Array *)map_node_array_new(node->a_count, mutid);
  1367. if (clone == NULL) {
  1368. return NULL;
  1369. }
  1370. /* Copy all elements from the current Array node to the new one. */
  1371. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1372. Py_XINCREF(node->a_array[i]);
  1373. clone->a_array[i] = node->a_array[i];
  1374. }
  1375. clone->a_mutid = mutid;
  1376. VALIDATE_ARRAY_NODE(clone)
  1377. return clone;
  1378. }
  1379. static MapNode *
  1380. map_node_array_assoc(MapNode_Array *self,
  1381. uint32_t shift, int32_t hash,
  1382. PyObject *key, PyObject *val, int* added_leaf,
  1383. uint64_t mutid)
  1384. {
  1385. /* Set a new key to this level (currently a Collision node)
  1386. of the tree.
  1387. Array nodes don't store values, they can only point to
  1388. other nodes. They are simple arrays of 32 BaseNode pointers/
  1389. */
  1390. uint32_t idx = map_mask(hash, shift);
  1391. MapNode *node = self->a_array[idx];
  1392. MapNode *child_node;
  1393. MapNode_Array *new_node;
  1394. Py_ssize_t i;
  1395. if (node == NULL) {
  1396. /* There's no child node for the given hash. Create a new
  1397. Bitmap node for this key. */
  1398. MapNode_Bitmap *empty = NULL;
  1399. /* Get an empty Bitmap node to work with. */
  1400. empty = (MapNode_Bitmap *)map_node_bitmap_new(0, mutid);
  1401. if (empty == NULL) {
  1402. return NULL;
  1403. }
  1404. /* Set key/val to the newly created empty Bitmap, thus
  1405. creating a new Bitmap node with our key/value pair. */
  1406. child_node = map_node_bitmap_assoc(
  1407. empty,
  1408. shift + 5, hash, key, val, added_leaf, mutid);
  1409. Py_DECREF(empty);
  1410. if (child_node == NULL) {
  1411. return NULL;
  1412. }
  1413. if (mutid != 0 && self->a_mutid == mutid) {
  1414. new_node = self;
  1415. self->a_count++;
  1416. Py_INCREF(self);
  1417. }
  1418. else {
  1419. /* Create a new Array node. */
  1420. new_node = (MapNode_Array *)map_node_array_new(
  1421. self->a_count + 1, mutid);
  1422. if (new_node == NULL) {
  1423. Py_DECREF(child_node);
  1424. return NULL;
  1425. }
  1426. /* Copy all elements from the current Array node to the
  1427. new one. */
  1428. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1429. Py_XINCREF(self->a_array[i]);
  1430. new_node->a_array[i] = self->a_array[i];
  1431. }
  1432. }
  1433. assert(new_node->a_array[idx] == NULL);
  1434. new_node->a_array[idx] = child_node; /* borrow */
  1435. VALIDATE_ARRAY_NODE(new_node)
  1436. }
  1437. else {
  1438. /* There's a child node for the given hash.
  1439. Set the key to it./ */
  1440. child_node = map_node_assoc(
  1441. node, shift + 5, hash, key, val, added_leaf, mutid);
  1442. if (child_node == NULL) {
  1443. return NULL;
  1444. }
  1445. else if (child_node == (MapNode *)self) {
  1446. Py_DECREF(child_node);
  1447. return (MapNode *)self;
  1448. }
  1449. if (mutid != 0 && self->a_mutid == mutid) {
  1450. new_node = self;
  1451. Py_INCREF(self);
  1452. }
  1453. else {
  1454. new_node = map_node_array_clone(self, mutid);
  1455. }
  1456. if (new_node == NULL) {
  1457. Py_DECREF(child_node);
  1458. return NULL;
  1459. }
  1460. Py_SETREF(new_node->a_array[idx], child_node); /* borrow */
  1461. VALIDATE_ARRAY_NODE(new_node)
  1462. }
  1463. return (MapNode *)new_node;
  1464. }
  1465. static map_without_t
  1466. map_node_array_without(MapNode_Array *self,
  1467. uint32_t shift, int32_t hash,
  1468. PyObject *key,
  1469. MapNode **new_node,
  1470. uint64_t mutid)
  1471. {
  1472. uint32_t idx = map_mask(hash, shift);
  1473. MapNode *node = self->a_array[idx];
  1474. if (node == NULL) {
  1475. return W_NOT_FOUND;
  1476. }
  1477. MapNode *sub_node = NULL;
  1478. MapNode_Array *target = NULL;
  1479. map_without_t res = map_node_without(
  1480. (MapNode *)node,
  1481. shift + 5, hash, key, &sub_node, mutid);
  1482. switch (res) {
  1483. case W_NOT_FOUND:
  1484. case W_ERROR:
  1485. assert(sub_node == NULL);
  1486. return res;
  1487. case W_NEWNODE: {
  1488. /* We need to replace a node at the `idx` index.
  1489. Clone this node and replace.
  1490. */
  1491. assert(sub_node != NULL);
  1492. if (mutid != 0 && self->a_mutid == mutid) {
  1493. target = self;
  1494. Py_INCREF(self);
  1495. }
  1496. else {
  1497. target = map_node_array_clone(self, mutid);
  1498. if (target == NULL) {
  1499. Py_DECREF(sub_node);
  1500. return W_ERROR;
  1501. }
  1502. }
  1503. Py_SETREF(target->a_array[idx], sub_node); /* borrow */
  1504. *new_node = (MapNode*)target; /* borrow */
  1505. return W_NEWNODE;
  1506. }
  1507. case W_EMPTY: {
  1508. assert(sub_node == NULL);
  1509. /* We need to remove a node at the `idx` index.
  1510. Calculate the size of the replacement Array node.
  1511. */
  1512. Py_ssize_t new_count = self->a_count - 1;
  1513. if (new_count == 0) {
  1514. return W_EMPTY;
  1515. }
  1516. if (new_count >= 16) {
  1517. /* We convert Bitmap nodes to Array nodes, when a
  1518. Bitmap node needs to store more than 15 key/value
  1519. pairs. So we will create a new Array node if we
  1520. the number of key/values after deletion is still
  1521. greater than 15.
  1522. */
  1523. if (mutid != 0 && self->a_mutid == mutid) {
  1524. target = self;
  1525. Py_INCREF(self);
  1526. }
  1527. else {
  1528. target = map_node_array_clone(self, mutid);
  1529. if (target == NULL) {
  1530. return W_ERROR;
  1531. }
  1532. }
  1533. target->a_count = new_count;
  1534. Py_CLEAR(target->a_array[idx]);
  1535. *new_node = (MapNode*)target; /* borrow */
  1536. return W_NEWNODE;
  1537. }
  1538. /* New Array node would have less than 16 key/value
  1539. pairs. We need to create a replacement Bitmap node. */
  1540. Py_ssize_t bitmap_size = new_count * 2;
  1541. uint32_t bitmap = 0;
  1542. MapNode_Bitmap *new = (MapNode_Bitmap *)
  1543. map_node_bitmap_new(bitmap_size, mutid);
  1544. if (new == NULL) {
  1545. return W_ERROR;
  1546. }
  1547. Py_ssize_t new_i = 0;
  1548. for (uint32_t i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1549. if (i == idx) {
  1550. /* Skip the node we are deleting. */
  1551. continue;
  1552. }
  1553. MapNode *node = self->a_array[i];
  1554. if (node == NULL) {
  1555. /* Skip any missing nodes. */
  1556. continue;
  1557. }
  1558. bitmap |= 1u << i;
  1559. if (IS_BITMAP_NODE(node)) {
  1560. MapNode_Bitmap *child = (MapNode_Bitmap *)node;
  1561. if (map_node_bitmap_count(child) == 1 &&
  1562. child->b_array[0] != NULL)
  1563. {
  1564. /* node is a Bitmap with one key/value pair, just
  1565. merge it into the new Bitmap node we're building.
  1566. Note that we don't inline Bitmap nodes that
  1567. have a NULL key -- those nodes point to another
  1568. tree level, and we cannot simply move tree levels
  1569. up or down.
  1570. */
  1571. PyObject *key = child->b_array[0];
  1572. PyObject *val = child->b_array[1];
  1573. Py_INCREF(key);
  1574. new->b_array[new_i] = key;
  1575. Py_INCREF(val);
  1576. new->b_array[new_i + 1] = val;
  1577. }
  1578. else {
  1579. new->b_array[new_i] = NULL;
  1580. Py_INCREF(node);
  1581. new->b_array[new_i + 1] = (PyObject*)node;
  1582. }
  1583. }
  1584. else {
  1585. #if !defined(NDEBUG)
  1586. if (IS_COLLISION_NODE(node)) {
  1587. assert(
  1588. (map_node_collision_count(
  1589. (MapNode_Collision*)node)) > 1);
  1590. }
  1591. else if (IS_ARRAY_NODE(node)) {
  1592. assert(((MapNode_Array*)node)->a_count >= 16);
  1593. }
  1594. #endif
  1595. /* Just copy the node into our new Bitmap */
  1596. new->b_array[new_i] = NULL;
  1597. Py_INCREF(node);
  1598. new->b_array[new_i + 1] = (PyObject*)node;
  1599. }
  1600. new_i += 2;
  1601. }
  1602. new->b_bitmap = bitmap;
  1603. *new_node = (MapNode*)new; /* borrow */
  1604. return W_NEWNODE;
  1605. }
  1606. default:
  1607. abort();
  1608. }
  1609. }
  1610. static map_find_t
  1611. map_node_array_find(MapNode_Array *self,
  1612. uint32_t shift, int32_t hash,
  1613. PyObject *key, PyObject **val)
  1614. {
  1615. /* Lookup `key` in the Array node `self`. Set the value
  1616. for the found key to 'val'. */
  1617. uint32_t idx = map_mask(hash, shift);
  1618. MapNode *node;
  1619. node = self->a_array[idx];
  1620. if (node == NULL) {
  1621. return F_NOT_FOUND;
  1622. }
  1623. /* Dispatch to the generic map_node_find */
  1624. return map_node_find(node, shift + 5, hash, key, val);
  1625. }
  1626. static int
  1627. map_node_array_traverse(MapNode_Array *self,
  1628. visitproc visit, void *arg)
  1629. {
  1630. /* Array's tp_traverse */
  1631. Py_ssize_t i;
  1632. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1633. Py_VISIT(self->a_array[i]);
  1634. }
  1635. return 0;
  1636. }
  1637. static void
  1638. map_node_array_dealloc(MapNode_Array *self)
  1639. {
  1640. /* Array's tp_dealloc */
  1641. Py_ssize_t i;
  1642. PyObject_GC_UnTrack(self);
  1643. Py_TRASHCAN_SAFE_BEGIN(self)
  1644. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1645. Py_XDECREF(self->a_array[i]);
  1646. }
  1647. Py_TYPE(self)->tp_free((PyObject *)self);
  1648. Py_TRASHCAN_SAFE_END(self)
  1649. }
  1650. static int
  1651. map_node_array_dump(MapNode_Array *node,
  1652. _PyUnicodeWriter *writer, int level)
  1653. {
  1654. /* Debug build: __dump__() method implementation for Array nodes. */
  1655. Py_ssize_t i;
  1656. if (_map_dump_ident(writer, level + 1)) {
  1657. goto error;
  1658. }
  1659. if (_map_dump_format(writer, "ArrayNode(id=%p count=%zd):\n",
  1660. node, node->a_count)
  1661. ) {
  1662. goto error;
  1663. }
  1664. for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1665. if (node->a_array[i] == NULL) {
  1666. continue;
  1667. }
  1668. if (_map_dump_ident(writer, level + 2)) {
  1669. goto error;
  1670. }
  1671. if (_map_dump_format(writer, "%d::\n", i)) {
  1672. goto error;
  1673. }
  1674. if (map_node_dump(node->a_array[i], writer, level + 1)) {
  1675. goto error;
  1676. }
  1677. if (_map_dump_format(writer, "\n")) {
  1678. goto error;
  1679. }
  1680. }
  1681. return 0;
  1682. error:
  1683. return -1;
  1684. }
  1685. /////////////////////////////////// Node Dispatch
  1686. static MapNode *
  1687. map_node_assoc(MapNode *node,
  1688. uint32_t shift, int32_t hash,
  1689. PyObject *key, PyObject *val, int* added_leaf,
  1690. uint64_t mutid)
  1691. {
  1692. /* Set key/value to the 'node' starting with the given shift/hash.
  1693. Return a new node, or the same node if key/value already
  1694. set.
  1695. added_leaf will be set to 1 if key/value wasn't in the
  1696. tree before.
  1697. This method automatically dispatches to the suitable
  1698. map_node_{nodetype}_assoc method.
  1699. */
  1700. *added_leaf = 0;
  1701. if (IS_BITMAP_NODE(node)) {
  1702. return map_node_bitmap_assoc(
  1703. (MapNode_Bitmap *)node,
  1704. shift, hash, key, val, added_leaf, mutid);
  1705. }
  1706. else if (IS_ARRAY_NODE(node)) {
  1707. return map_node_array_assoc(
  1708. (MapNode_Array *)node,
  1709. shift, hash, key, val, added_leaf, mutid);
  1710. }
  1711. else {
  1712. assert(IS_COLLISION_NODE(node));
  1713. return map_node_collision_assoc(
  1714. (MapNode_Collision *)node,
  1715. shift, hash, key, val, added_leaf, mutid);
  1716. }
  1717. }
  1718. static map_without_t
  1719. map_node_without(MapNode *node,
  1720. uint32_t shift, int32_t hash,
  1721. PyObject *key,
  1722. MapNode **new_node,
  1723. uint64_t mutid)
  1724. {
  1725. if (IS_BITMAP_NODE(node)) {
  1726. return map_node_bitmap_without(
  1727. (MapNode_Bitmap *)node,
  1728. shift, hash, key,
  1729. new_node,
  1730. mutid);
  1731. }
  1732. else if (IS_ARRAY_NODE(node)) {
  1733. return map_node_array_without(
  1734. (MapNode_Array *)node,
  1735. shift, hash, key,
  1736. new_node,
  1737. mutid);
  1738. }
  1739. else {
  1740. assert(IS_COLLISION_NODE(node));
  1741. return map_node_collision_without(
  1742. (MapNode_Collision *)node,
  1743. shift, hash, key,
  1744. new_node,
  1745. mutid);
  1746. }
  1747. }
  1748. static map_find_t
  1749. map_node_find(MapNode *node,
  1750. uint32_t shift, int32_t hash,
  1751. PyObject *key, PyObject **val)
  1752. {
  1753. /* Find the key in the node starting with the given shift/hash.
  1754. If a value is found, the result will be set to F_FOUND, and
  1755. *val will point to the found value object.
  1756. If a value wasn't found, the result will be set to F_NOT_FOUND.
  1757. If an exception occurs during the call, the result will be F_ERROR.
  1758. This method automatically dispatches to the suitable
  1759. map_node_{nodetype}_find method.
  1760. */
  1761. if (IS_BITMAP_NODE(node)) {
  1762. return map_node_bitmap_find(
  1763. (MapNode_Bitmap *)node,
  1764. shift, hash, key, val);
  1765. }
  1766. else if (IS_ARRAY_NODE(node)) {
  1767. return map_node_array_find(
  1768. (MapNode_Array *)node,
  1769. shift, hash, key, val);
  1770. }
  1771. else {
  1772. assert(IS_COLLISION_NODE(node));
  1773. return map_node_collision_find(
  1774. (MapNode_Collision *)node,
  1775. shift, hash, key, val);
  1776. }
  1777. }
  1778. static int
  1779. map_node_dump(MapNode *node,
  1780. _PyUnicodeWriter *writer, int level)
  1781. {
  1782. /* Debug build: __dump__() method implementation for a node.
  1783. This method automatically dispatches to the suitable
  1784. map_node_{nodetype})_dump method.
  1785. */
  1786. if (IS_BITMAP_NODE(node)) {
  1787. return map_node_bitmap_dump(
  1788. (MapNode_Bitmap *)node, writer, level);
  1789. }
  1790. else if (IS_ARRAY_NODE(node)) {
  1791. return map_node_array_dump(
  1792. (MapNode_Array *)node, writer, level);
  1793. }
  1794. else {
  1795. assert(IS_COLLISION_NODE(node));
  1796. return map_node_collision_dump(
  1797. (MapNode_Collision *)node, writer, level);
  1798. }
  1799. }
  1800. /////////////////////////////////// Iterators: Machinery
  1801. static map_iter_t
  1802. map_iterator_next(MapIteratorState *iter, PyObject **key, PyObject **val);
  1803. static void
  1804. map_iterator_init(MapIteratorState *iter, MapNode *root)
  1805. {
  1806. for (uint32_t i = 0; i < _Py_HAMT_MAX_TREE_DEPTH; i++) {
  1807. iter->i_nodes[i] = NULL;
  1808. iter->i_pos[i] = 0;
  1809. }
  1810. iter->i_level = 0;
  1811. /* Note: we don't incref/decref nodes in i_nodes. */
  1812. iter->i_nodes[0] = root;
  1813. }
  1814. static map_iter_t
  1815. map_iterator_bitmap_next(MapIteratorState *iter,
  1816. PyObject **key, PyObject **val)
  1817. {
  1818. int8_t level = iter->i_level;
  1819. MapNode_Bitmap *node = (MapNode_Bitmap *)(iter->i_nodes[level]);
  1820. Py_ssize_t pos = iter->i_pos[level];
  1821. if (pos + 1 >= Py_SIZE(node)) {
  1822. #if !defined(NDEBUG)
  1823. assert(iter->i_level >= 0);
  1824. iter->i_nodes[iter->i_level] = NULL;
  1825. #endif
  1826. iter->i_level--;
  1827. return map_iterator_next(iter, key, val);
  1828. }
  1829. if (node->b_array[pos] == NULL) {
  1830. iter->i_pos[level] = pos + 2;
  1831. assert(level + 1 < _Py_HAMT_MAX_TREE_DEPTH);
  1832. int8_t next_level = (int8_t)(level + 1);
  1833. iter->i_level = next_level;
  1834. iter->i_pos[next_level] = 0;
  1835. iter->i_nodes[next_level] = (MapNode *)
  1836. node->b_array[pos + 1];
  1837. return map_iterator_next(iter, key, val);
  1838. }
  1839. *key = node->b_array[pos];
  1840. *val = node->b_array[pos + 1];
  1841. iter->i_pos[level] = pos + 2;
  1842. return I_ITEM;
  1843. }
  1844. static map_iter_t
  1845. map_iterator_collision_next(MapIteratorState *iter,
  1846. PyObject **key, PyObject **val)
  1847. {
  1848. int8_t level = iter->i_level;
  1849. MapNode_Collision *node = (MapNode_Collision *)(iter->i_nodes[level]);
  1850. Py_ssize_t pos = iter->i_pos[level];
  1851. if (pos + 1 >= Py_SIZE(node)) {
  1852. #if !defined(NDEBUG)
  1853. assert(iter->i_level >= 0);
  1854. iter->i_nodes[iter->i_level] = NULL;
  1855. #endif
  1856. iter->i_level--;
  1857. return map_iterator_next(iter, key, val);
  1858. }
  1859. *key = node->c_array[pos];
  1860. *val = node->c_array[pos + 1];
  1861. iter->i_pos[level] = pos + 2;
  1862. return I_ITEM;
  1863. }
  1864. static map_iter_t
  1865. map_iterator_array_next(MapIteratorState *iter,
  1866. PyObject **key, PyObject **val)
  1867. {
  1868. int8_t level = iter->i_level;
  1869. MapNode_Array *node = (MapNode_Array *)(iter->i_nodes[level]);
  1870. Py_ssize_t pos = iter->i_pos[level];
  1871. if (pos >= HAMT_ARRAY_NODE_SIZE) {
  1872. #if !defined(NDEBUG)
  1873. assert(iter->i_level >= 0);
  1874. iter->i_nodes[iter->i_level] = NULL;
  1875. #endif
  1876. iter->i_level--;
  1877. return map_iterator_next(iter, key, val);
  1878. }
  1879. for (Py_ssize_t i = pos; i < HAMT_ARRAY_NODE_SIZE; i++) {
  1880. if (node->a_array[i] != NULL) {
  1881. iter->i_pos[level] = i + 1;
  1882. assert((level + 1) < _Py_HAMT_MAX_TREE_DEPTH);
  1883. int8_t next_level = (int8_t)(level + 1);
  1884. iter->i_pos[next_level] = 0;
  1885. iter->i_nodes[next_level] = node->a_array[i];
  1886. iter->i_level = next_level;
  1887. return map_iterator_next(iter, key, val);
  1888. }
  1889. }
  1890. #if !defined(NDEBUG)
  1891. assert(iter->i_level >= 0);
  1892. iter->i_nodes[iter->i_level] = NULL;
  1893. #endif
  1894. iter->i_level--;
  1895. return map_iterator_next(iter, key, val);
  1896. }
  1897. static map_iter_t
  1898. map_iterator_next(MapIteratorState *iter, PyObject **key, PyObject **val)
  1899. {
  1900. if (iter->i_level < 0) {
  1901. return I_END;
  1902. }
  1903. assert(iter->i_level < _Py_HAMT_MAX_TREE_DEPTH);
  1904. MapNode *current = iter->i_nodes[iter->i_level];
  1905. if (IS_BITMAP_NODE(current)) {
  1906. return map_iterator_bitmap_next(iter, key, val);
  1907. }
  1908. else if (IS_ARRAY_NODE(current)) {
  1909. return map_iterator_array_next(iter, key, val);
  1910. }
  1911. else {
  1912. assert(IS_COLLISION_NODE(current));
  1913. return map_iterator_collision_next(iter, key, val);
  1914. }
  1915. }
  1916. /////////////////////////////////// HAMT high-level functions
  1917. static MapObject *
  1918. map_assoc(MapObject *o, PyObject *key, PyObject *val)
  1919. {
  1920. int32_t key_hash;
  1921. int added_leaf = 0;
  1922. MapNode *new_root;
  1923. MapObject *new_o;
  1924. key_hash = map_hash(key);
  1925. if (key_hash == -1) {
  1926. return NULL;
  1927. }
  1928. new_root = map_node_assoc(
  1929. (MapNode *)(o->h_root),
  1930. 0, key_hash, key, val, &added_leaf,
  1931. 0);
  1932. if (new_root == NULL) {
  1933. return NULL;
  1934. }
  1935. if (new_root == o->h_root) {
  1936. Py_DECREF(new_root);
  1937. Py_INCREF(o);
  1938. return o;
  1939. }
  1940. new_o = map_alloc();
  1941. if (new_o == NULL) {
  1942. Py_DECREF(new_root);
  1943. return NULL;
  1944. }
  1945. new_o->h_root = new_root; /* borrow */
  1946. new_o->h_count = added_leaf ? o->h_count + 1 : o->h_count;
  1947. return new_o;
  1948. }
  1949. static MapObject *
  1950. map_without(MapObject *o, PyObject *key)
  1951. {
  1952. int32_t key_hash = map_hash(key);
  1953. if (key_hash == -1) {
  1954. return NULL;
  1955. }
  1956. MapNode *new_root = NULL;
  1957. map_without_t res = map_node_without(
  1958. (MapNode *)(o->h_root),
  1959. 0, key_hash, key,
  1960. &new_root,
  1961. 0);
  1962. switch (res) {
  1963. case W_ERROR:
  1964. return NULL;
  1965. case W_EMPTY:
  1966. return map_new();
  1967. case W_NOT_FOUND:
  1968. PyErr_SetObject(PyExc_KeyError, key);
  1969. return NULL;
  1970. case W_NEWNODE: {
  1971. assert(new_root != NULL);
  1972. MapObject *new_o = map_alloc();
  1973. if (new_o == NULL) {
  1974. Py_DECREF(new_root);
  1975. return NULL;
  1976. }
  1977. new_o->h_root = new_root; /* borrow */
  1978. new_o->h_count = o->h_count - 1;
  1979. assert(new_o->h_count >= 0);
  1980. return new_o;
  1981. }
  1982. default:
  1983. abort();
  1984. }
  1985. }
  1986. static map_find_t
  1987. map_find(BaseMapObject *o, PyObject *key, PyObject **val)
  1988. {
  1989. if (o->b_count == 0) {
  1990. return F_NOT_FOUND;
  1991. }
  1992. int32_t key_hash = map_hash(key);
  1993. if (key_hash == -1) {
  1994. return F_ERROR;
  1995. }
  1996. return map_node_find(o->b_root, 0, key_hash, key, val);
  1997. }
  1998. static int
  1999. map_eq(BaseMapObject *v, BaseMapObject *w)
  2000. {
  2001. if (v == w) {
  2002. return 1;
  2003. }
  2004. if (v->b_count != w->b_count) {
  2005. return 0;
  2006. }
  2007. MapIteratorState iter;
  2008. map_iter_t iter_res;
  2009. map_find_t find_res;
  2010. PyObject *v_key;
  2011. PyObject *v_val;
  2012. PyObject *w_val;
  2013. map_iterator_init(&iter, v->b_root);
  2014. do {
  2015. iter_res = map_iterator_next(&iter, &v_key, &v_val);
  2016. if (iter_res == I_ITEM) {
  2017. find_res = map_find(w, v_key, &w_val);
  2018. switch (find_res) {
  2019. case F_ERROR:
  2020. return -1;
  2021. case F_NOT_FOUND:
  2022. return 0;
  2023. case F_FOUND: {
  2024. int cmp = PyObject_RichCompareBool(v_val, w_val, Py_EQ);
  2025. if (cmp < 0) {
  2026. return -1;
  2027. }
  2028. if (cmp == 0) {
  2029. return 0;
  2030. }
  2031. }
  2032. }
  2033. }
  2034. } while (iter_res != I_END);
  2035. return 1;
  2036. }
  2037. static Py_ssize_t
  2038. map_len(BaseMapObject *o)
  2039. {
  2040. return o->b_count;
  2041. }
  2042. static MapObject *
  2043. map_alloc(void)
  2044. {
  2045. MapObject *o;
  2046. o = PyObject_GC_New(MapObject, &_Map_Type);
  2047. if (o == NULL) {
  2048. return NULL;
  2049. }
  2050. o->h_weakreflist = NULL;
  2051. o->h_hash = -1;
  2052. o->h_count = 0;
  2053. o->h_root = NULL;
  2054. PyObject_GC_Track(o);
  2055. return o;
  2056. }
  2057. static MapObject *
  2058. map_new(void)
  2059. {
  2060. MapObject *o = map_alloc();
  2061. if (o == NULL) {
  2062. return NULL;
  2063. }
  2064. o->h_root = map_node_bitmap_new(0, 0);
  2065. if (o->h_root == NULL) {
  2066. Py_DECREF(o);
  2067. return NULL;
  2068. }
  2069. return o;
  2070. }
  2071. static PyObject *
  2072. map_dump(MapObject *self)
  2073. {
  2074. _PyUnicodeWriter writer;
  2075. _PyUnicodeWriter_Init(&writer);
  2076. if (_map_dump_format(&writer, "HAMT(len=%zd):\n", self->h_count)) {
  2077. goto error;
  2078. }
  2079. if (map_node_dump(self->h_root, &writer, 0)) {
  2080. goto error;
  2081. }
  2082. return _PyUnicodeWriter_Finish(&writer);
  2083. error:
  2084. _PyUnicodeWriter_Dealloc(&writer);
  2085. return NULL;
  2086. }
  2087. /////////////////////////////////// Iterators: Shared Iterator Implementation
  2088. static int
  2089. map_baseiter_tp_clear(MapIterator *it)
  2090. {
  2091. Py_CLEAR(it->mi_obj);
  2092. return 0;
  2093. }
  2094. static void
  2095. map_baseiter_tp_dealloc(MapIterator *it)
  2096. {
  2097. PyObject_GC_UnTrack(it);
  2098. (void)map_baseiter_tp_clear(it);
  2099. PyObject_GC_Del(it);
  2100. }
  2101. static int
  2102. map_baseiter_tp_traverse(MapIterator *it, visitproc visit, void *arg)
  2103. {
  2104. Py_VISIT(it->mi_obj);
  2105. return 0;
  2106. }
  2107. static PyObject *
  2108. map_baseiter_tp_iternext(MapIterator *it)
  2109. {
  2110. PyObject *key;
  2111. PyObject *val;
  2112. map_iter_t res = map_iterator_next(&it->mi_iter, &key, &val);
  2113. switch (res) {
  2114. case I_END:
  2115. PyErr_SetNone(PyExc_StopIteration);
  2116. return NULL;
  2117. case I_ITEM: {
  2118. return (*(it->mi_yield))(key, val);
  2119. }
  2120. default: {
  2121. abort();
  2122. }
  2123. }
  2124. }
  2125. static int
  2126. map_baseview_tp_clear(MapView *view)
  2127. {
  2128. Py_CLEAR(view->mv_obj);
  2129. Py_CLEAR(view->mv_itertype);
  2130. return 0;
  2131. }
  2132. static void
  2133. map_baseview_tp_dealloc(MapView *view)
  2134. {
  2135. PyObject_GC_UnTrack(view);
  2136. (void)map_baseview_tp_clear(view);
  2137. PyObject_GC_Del(view);
  2138. }
  2139. static int
  2140. map_baseview_tp_traverse(MapView *view, visitproc visit, void *arg)
  2141. {
  2142. Py_VISIT(view->mv_obj);
  2143. return 0;
  2144. }
  2145. static Py_ssize_t
  2146. map_baseview_tp_len(MapView *view)
  2147. {
  2148. return view->mv_obj->h_count;
  2149. }
  2150. static PyMappingMethods MapView_as_mapping = {
  2151. (lenfunc)map_baseview_tp_len,
  2152. };
  2153. static PyObject *
  2154. map_baseview_newiter(PyTypeObject *type, binaryfunc yield, MapObject *map)
  2155. {
  2156. MapIterator *iter = PyObject_GC_New(MapIterator, type);
  2157. if (iter == NULL) {
  2158. return NULL;
  2159. }
  2160. Py_INCREF(map);
  2161. iter->mi_obj = map;
  2162. iter->mi_yield = yield;
  2163. map_iterator_init(&iter->mi_iter, map->h_root);
  2164. PyObject_GC_Track(iter);
  2165. return (PyObject *)iter;
  2166. }
  2167. static PyObject *
  2168. map_baseview_iter(MapView *view)
  2169. {
  2170. return map_baseview_newiter(
  2171. view->mv_itertype, view->mv_yield, view->mv_obj);
  2172. }
  2173. static PyObject *
  2174. map_baseview_new(PyTypeObject *type, binaryfunc yield,
  2175. MapObject *o, PyTypeObject *itertype)
  2176. {
  2177. MapView *view = PyObject_GC_New(MapView, type);
  2178. if (view == NULL) {
  2179. return NULL;
  2180. }
  2181. Py_INCREF(o);
  2182. view->mv_obj = o;
  2183. view->mv_yield = yield;
  2184. Py_INCREF(itertype);
  2185. view->mv_itertype = itertype;
  2186. PyObject_GC_Track(view);
  2187. return (PyObject *)view;
  2188. }
  2189. #define ITERATOR_TYPE_SHARED_SLOTS \
  2190. .tp_basicsize = sizeof(MapIterator), \
  2191. .tp_itemsize = 0, \
  2192. .tp_dealloc = (destructor)map_baseiter_tp_dealloc, \
  2193. .tp_getattro = PyObject_GenericGetAttr, \
  2194. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \
  2195. .tp_traverse = (traverseproc)map_baseiter_tp_traverse, \
  2196. .tp_clear = (inquiry)map_baseiter_tp_clear, \
  2197. .tp_iter = PyObject_SelfIter, \
  2198. .tp_iternext = (iternextfunc)map_baseiter_tp_iternext,
  2199. #define VIEW_TYPE_SHARED_SLOTS \
  2200. .tp_basicsize = sizeof(MapView), \
  2201. .tp_itemsize = 0, \
  2202. .tp_as_mapping = &MapView_as_mapping, \
  2203. .tp_dealloc = (destructor)map_baseview_tp_dealloc, \
  2204. .tp_getattro = PyObject_GenericGetAttr, \
  2205. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, \
  2206. .tp_traverse = (traverseproc)map_baseview_tp_traverse, \
  2207. .tp_clear = (inquiry)map_baseview_tp_clear, \
  2208. .tp_iter = (getiterfunc)map_baseview_iter, \
  2209. /////////////////////////////////// _MapItems_Type
  2210. PyTypeObject _MapItems_Type = {
  2211. PyVarObject_HEAD_INIT(NULL, 0)
  2212. "items",
  2213. VIEW_TYPE_SHARED_SLOTS
  2214. };
  2215. PyTypeObject _MapItemsIter_Type = {
  2216. PyVarObject_HEAD_INIT(NULL, 0)
  2217. "items_iterator",
  2218. ITERATOR_TYPE_SHARED_SLOTS
  2219. };
  2220. static PyObject *
  2221. map_iter_yield_items(PyObject *key, PyObject *val)
  2222. {
  2223. return PyTuple_Pack(2, key, val);
  2224. }
  2225. static PyObject *
  2226. map_new_items_view(MapObject *o)
  2227. {
  2228. return map_baseview_new(
  2229. &_MapItems_Type, map_iter_yield_items, o,
  2230. &_MapItemsIter_Type);
  2231. }
  2232. /////////////////////////////////// _MapKeys_Type
  2233. PyTypeObject _MapKeys_Type = {
  2234. PyVarObject_HEAD_INIT(NULL, 0)
  2235. "keys",
  2236. VIEW_TYPE_SHARED_SLOTS
  2237. };
  2238. PyTypeObject _MapKeysIter_Type = {
  2239. PyVarObject_HEAD_INIT(NULL, 0)
  2240. "keys_iterator",
  2241. ITERATOR_TYPE_SHARED_SLOTS
  2242. };
  2243. static PyObject *
  2244. map_iter_yield_keys(PyObject *key, PyObject *val)
  2245. {
  2246. Py_INCREF(key);
  2247. return key;
  2248. }
  2249. static PyObject *
  2250. map_new_keys_iter(MapObject *o)
  2251. {
  2252. return map_baseview_newiter(
  2253. &_MapKeysIter_Type, map_iter_yield_keys, o);
  2254. }
  2255. static PyObject *
  2256. map_new_keys_view(MapObject *o)
  2257. {
  2258. return map_baseview_new(
  2259. &_MapKeys_Type, map_iter_yield_keys, o,
  2260. &_MapKeysIter_Type);
  2261. }
  2262. /////////////////////////////////// _MapValues_Type
  2263. PyTypeObject _MapValues_Type = {
  2264. PyVarObject_HEAD_INIT(NULL, 0)
  2265. "values",
  2266. VIEW_TYPE_SHARED_SLOTS
  2267. };
  2268. PyTypeObject _MapValuesIter_Type = {
  2269. PyVarObject_HEAD_INIT(NULL, 0)
  2270. "values_iterator",
  2271. ITERATOR_TYPE_SHARED_SLOTS
  2272. };
  2273. static PyObject *
  2274. map_iter_yield_values(PyObject *key, PyObject *val)
  2275. {
  2276. Py_INCREF(val);
  2277. return val;
  2278. }
  2279. static PyObject *
  2280. map_new_values_view(MapObject *o)
  2281. {
  2282. return map_baseview_new(
  2283. &_MapValues_Type, map_iter_yield_values, o,
  2284. &_MapValuesIter_Type);
  2285. }
  2286. /////////////////////////////////// _Map_Type
  2287. static PyObject *
  2288. map_dump(MapObject *self);
  2289. static PyObject *
  2290. map_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  2291. {
  2292. return (PyObject*)map_new();
  2293. }
  2294. static int
  2295. map_tp_init(MapObject *self, PyObject *args, PyObject *kwds)
  2296. {
  2297. PyObject *arg = NULL;
  2298. uint64_t mutid = 0;
  2299. if (!PyArg_UnpackTuple(args, "immutables.Map", 0, 1, &arg)) {
  2300. return -1;
  2301. }
  2302. if (arg != NULL) {
  2303. if (Map_Check(arg)) {
  2304. MapObject *other = (MapObject *)arg;
  2305. Py_INCREF(other->h_root);
  2306. Py_SETREF(self->h_root, other->h_root);
  2307. self->h_count = other->h_count;
  2308. self->h_hash = other->h_hash;
  2309. }
  2310. else if (MapMutation_Check(arg)) {
  2311. PyErr_Format(
  2312. PyExc_TypeError,
  2313. "cannot create Maps from MapMutations");
  2314. return -1;
  2315. }
  2316. else {
  2317. mutid = mutid_counter++;
  2318. if (map_update_inplace(mutid, (BaseMapObject *)self, arg)) {
  2319. return -1;
  2320. }
  2321. }
  2322. }
  2323. if (kwds != NULL) {
  2324. if (!PyArg_ValidateKeywordArguments(kwds)) {
  2325. return -1;
  2326. }
  2327. if (!mutid) {
  2328. mutid = mutid_counter++;
  2329. }
  2330. if (map_update_inplace(mutid, (BaseMapObject *)self, kwds)) {
  2331. return -1;
  2332. }
  2333. }
  2334. return 0;
  2335. }
  2336. static int
  2337. map_tp_clear(BaseMapObject *self)
  2338. {
  2339. Py_CLEAR(self->b_root);
  2340. return 0;
  2341. }
  2342. static int
  2343. map_tp_traverse(BaseMapObject *self, visitproc visit, void *arg)
  2344. {
  2345. Py_VISIT(self->b_root);
  2346. return 0;
  2347. }
  2348. static void
  2349. map_tp_dealloc(BaseMapObject *self)
  2350. {
  2351. PyObject_GC_UnTrack(self);
  2352. if (self->b_weakreflist != NULL) {
  2353. PyObject_ClearWeakRefs((PyObject*)self);
  2354. }
  2355. (void)map_tp_clear(self);
  2356. Py_TYPE(self)->tp_free(self);
  2357. }
  2358. static PyObject *
  2359. map_tp_richcompare(PyObject *v, PyObject *w, int op)
  2360. {
  2361. if (!Map_Check(v) || !Map_Check(w) || (op != Py_EQ && op != Py_NE)) {
  2362. Py_RETURN_NOTIMPLEMENTED;
  2363. }
  2364. int res = map_eq((BaseMapObject *)v, (BaseMapObject *)w);
  2365. if (res < 0) {
  2366. return NULL;
  2367. }
  2368. if (op == Py_NE) {
  2369. res = !res;
  2370. }
  2371. if (res) {
  2372. Py_RETURN_TRUE;
  2373. }
  2374. else {
  2375. Py_RETURN_FALSE;
  2376. }
  2377. }
  2378. static int
  2379. map_tp_contains(BaseMapObject *self, PyObject *key)
  2380. {
  2381. PyObject *val;
  2382. map_find_t res = map_find(self, key, &val);
  2383. switch (res) {
  2384. case F_ERROR:
  2385. return -1;
  2386. case F_NOT_FOUND:
  2387. return 0;
  2388. case F_FOUND:
  2389. return 1;
  2390. default:
  2391. abort();
  2392. }
  2393. }
  2394. static PyObject *
  2395. map_tp_subscript(BaseMapObject *self, PyObject *key)
  2396. {
  2397. PyObject *val;
  2398. map_find_t res = map_find(self, key, &val);
  2399. switch (res) {
  2400. case F_ERROR:
  2401. return NULL;
  2402. case F_FOUND:
  2403. Py_INCREF(val);
  2404. return val;
  2405. case F_NOT_FOUND:
  2406. PyErr_SetObject(PyExc_KeyError, key);
  2407. return NULL;
  2408. default:
  2409. abort();
  2410. }
  2411. }
  2412. static Py_ssize_t
  2413. map_tp_len(BaseMapObject *self)
  2414. {
  2415. return map_len(self);
  2416. }
  2417. static PyObject *
  2418. map_tp_iter(MapObject *self)
  2419. {
  2420. return map_new_keys_iter(self);
  2421. }
  2422. static PyObject *
  2423. map_py_set(MapObject *self, PyObject *args)
  2424. {
  2425. PyObject *key;
  2426. PyObject *val;
  2427. if (!PyArg_UnpackTuple(args, "set", 2, 2, &key, &val)) {
  2428. return NULL;
  2429. }
  2430. return (PyObject *)map_assoc(self, key, val);
  2431. }
  2432. static PyObject *
  2433. map_py_get(BaseMapObject *self, PyObject *args)
  2434. {
  2435. PyObject *key;
  2436. PyObject *def = NULL;
  2437. if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) {
  2438. return NULL;
  2439. }
  2440. PyObject *val = NULL;
  2441. map_find_t res = map_find(self, key, &val);
  2442. switch (res) {
  2443. case F_ERROR:
  2444. return NULL;
  2445. case F_FOUND:
  2446. Py_INCREF(val);
  2447. return val;
  2448. case F_NOT_FOUND:
  2449. if (def == NULL) {
  2450. Py_RETURN_NONE;
  2451. }
  2452. Py_INCREF(def);
  2453. return def;
  2454. default:
  2455. abort();
  2456. }
  2457. }
  2458. static PyObject *
  2459. map_py_delete(MapObject *self, PyObject *key)
  2460. {
  2461. return (PyObject *)map_without(self, key);
  2462. }
  2463. static PyObject *
  2464. map_py_mutate(MapObject *self, PyObject *args)
  2465. {
  2466. MapMutationObject *o;
  2467. o = PyObject_GC_New(MapMutationObject, &_MapMutation_Type);
  2468. if (o == NULL) {
  2469. return NULL;
  2470. }
  2471. o->m_weakreflist = NULL;
  2472. o->m_count = self->h_count;
  2473. Py_INCREF(self->h_root);
  2474. o->m_root = self->h_root;
  2475. o->m_mutid = mutid_counter++;
  2476. PyObject_GC_Track(o);
  2477. return (PyObject *)o;
  2478. }
  2479. static PyObject *
  2480. map_py_update(MapObject *self, PyObject *args, PyObject *kwds)
  2481. {
  2482. PyObject *arg = NULL;
  2483. MapObject *new = NULL;
  2484. uint64_t mutid = 0;
  2485. if (!PyArg_UnpackTuple(args, "update", 0, 1, &arg)) {
  2486. return NULL;
  2487. }
  2488. if (arg != NULL) {
  2489. mutid = mutid_counter++;
  2490. new = map_update(mutid, self, arg);
  2491. if (new == NULL) {
  2492. return NULL;
  2493. }
  2494. }
  2495. else {
  2496. Py_INCREF(self);
  2497. new = self;
  2498. }
  2499. if (kwds != NULL) {
  2500. if (!PyArg_ValidateKeywordArguments(kwds)) {
  2501. Py_DECREF(new);
  2502. return NULL;
  2503. }
  2504. if (!mutid) {
  2505. mutid = mutid_counter++;
  2506. }
  2507. MapObject *new2 = map_update(mutid, new, kwds);
  2508. Py_DECREF(new);
  2509. if (new2 == NULL) {
  2510. return NULL;
  2511. }
  2512. new = new2;
  2513. }
  2514. return (PyObject *)new;
  2515. }
  2516. static PyObject *
  2517. map_py_items(MapObject *self, PyObject *args)
  2518. {
  2519. return map_new_items_view(self);
  2520. }
  2521. static PyObject *
  2522. map_py_values(MapObject *self, PyObject *args)
  2523. {
  2524. return map_new_values_view(self);
  2525. }
  2526. static PyObject *
  2527. map_py_keys(MapObject *self, PyObject *args)
  2528. {
  2529. return map_new_keys_view(self);
  2530. }
  2531. static PyObject *
  2532. map_py_dump(MapObject *self, PyObject *args)
  2533. {
  2534. return map_dump(self);
  2535. }
  2536. static PyObject *
  2537. map_py_repr(BaseMapObject *m)
  2538. {
  2539. Py_ssize_t i;
  2540. _PyUnicodeWriter writer;
  2541. i = Py_ReprEnter((PyObject *)m);
  2542. if (i != 0) {
  2543. return i > 0 ? PyUnicode_FromString("{...}") : NULL;
  2544. }
  2545. _PyUnicodeWriter_Init(&writer);
  2546. if (MapMutation_Check(m)) {
  2547. if (_PyUnicodeWriter_WriteASCIIString(
  2548. &writer, "immutables.MapMutation({", 24) < 0)
  2549. {
  2550. goto error;
  2551. }
  2552. }
  2553. else {
  2554. if (_PyUnicodeWriter_WriteASCIIString(
  2555. &writer, "immutables.Map({", 16) < 0)
  2556. {
  2557. goto error;
  2558. }
  2559. }
  2560. MapIteratorState iter;
  2561. map_iter_t iter_res;
  2562. map_iterator_init(&iter, m->b_root);
  2563. int second = 0;
  2564. do {
  2565. PyObject *v_key;
  2566. PyObject *v_val;
  2567. iter_res = map_iterator_next(&iter, &v_key, &v_val);
  2568. if (iter_res == I_ITEM) {
  2569. if (second) {
  2570. if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
  2571. goto error;
  2572. }
  2573. }
  2574. PyObject *s = PyObject_Repr(v_key);
  2575. if (s == NULL) {
  2576. goto error;
  2577. }
  2578. if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) {
  2579. Py_DECREF(s);
  2580. goto error;
  2581. }
  2582. Py_DECREF(s);
  2583. if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0) {
  2584. goto error;
  2585. }
  2586. s = PyObject_Repr(v_val);
  2587. if (s == NULL) {
  2588. goto error;
  2589. }
  2590. if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) {
  2591. Py_DECREF(s);
  2592. goto error;
  2593. }
  2594. Py_DECREF(s);
  2595. }
  2596. second = 1;
  2597. } while (iter_res != I_END);
  2598. if (_PyUnicodeWriter_WriteASCIIString(&writer, "})", 2) < 0) {
  2599. goto error;
  2600. }
  2601. Py_ReprLeave((PyObject *)m);
  2602. return _PyUnicodeWriter_Finish(&writer);
  2603. error:
  2604. _PyUnicodeWriter_Dealloc(&writer);
  2605. Py_ReprLeave((PyObject *)m);
  2606. return NULL;
  2607. }
  2608. static Py_uhash_t
  2609. _shuffle_bits(Py_uhash_t h)
  2610. {
  2611. return ((h ^ 89869747UL) ^ (h << 16)) * 3644798167UL;
  2612. }
  2613. static Py_hash_t
  2614. map_py_hash(MapObject *self)
  2615. {
  2616. /* Adapted version of frozenset.__hash__: it's important
  2617. that Map.__hash__ is independant of key/values order.
  2618. Optimization idea: compute and memoize intermediate
  2619. hash values for HAMT nodes.
  2620. */
  2621. if (self->h_hash != -1) {
  2622. return self->h_hash;
  2623. }
  2624. Py_uhash_t hash = 0;
  2625. MapIteratorState iter;
  2626. map_iter_t iter_res;
  2627. map_iterator_init(&iter, self->h_root);
  2628. do {
  2629. PyObject *v_key;
  2630. PyObject *v_val;
  2631. iter_res = map_iterator_next(&iter, &v_key, &v_val);
  2632. if (iter_res == I_ITEM) {
  2633. Py_hash_t vh = PyObject_Hash(v_key);
  2634. if (vh == -1) {
  2635. return -1;
  2636. }
  2637. hash ^= _shuffle_bits((Py_uhash_t)vh);
  2638. vh = PyObject_Hash(v_val);
  2639. if (vh == -1) {
  2640. return -1;
  2641. }
  2642. hash ^= _shuffle_bits((Py_uhash_t)vh);
  2643. }
  2644. } while (iter_res != I_END);
  2645. hash ^= ((Py_uhash_t)self->h_count * 2 + 1) * 1927868237UL;
  2646. hash ^= (hash >> 11) ^ (hash >> 25);
  2647. hash = hash * 69069U + 907133923UL;
  2648. self->h_hash = (Py_hash_t)hash;
  2649. if (self->h_hash == -1) {
  2650. self->h_hash = 1;
  2651. }
  2652. return self->h_hash;
  2653. }
  2654. static PyObject *
  2655. map_reduce(MapObject *self)
  2656. {
  2657. MapIteratorState iter;
  2658. map_iter_t iter_res;
  2659. PyObject *dict = PyDict_New();
  2660. if (dict == NULL) {
  2661. return NULL;
  2662. }
  2663. map_iterator_init(&iter, self->h_root);
  2664. do {
  2665. PyObject *key;
  2666. PyObject *val;
  2667. iter_res = map_iterator_next(&iter, &key, &val);
  2668. if (iter_res == I_ITEM) {
  2669. if (PyDict_SetItem(dict, key, val) < 0) {
  2670. Py_DECREF(dict);
  2671. return NULL;
  2672. }
  2673. }
  2674. } while (iter_res != I_END);
  2675. PyObject *args = PyTuple_Pack(1, dict);
  2676. Py_DECREF(dict);
  2677. if (args == NULL) {
  2678. return NULL;
  2679. }
  2680. PyObject *tup = PyTuple_Pack(2, Py_TYPE(self), args);
  2681. Py_DECREF(args);
  2682. return tup;
  2683. }
  2684. static PyObject *
  2685. map_py_class_getitem(PyObject *type, PyObject *item)
  2686. {
  2687. Py_INCREF(type);
  2688. return type;
  2689. }
  2690. static PyMethodDef Map_methods[] = {
  2691. {"set", (PyCFunction)map_py_set, METH_VARARGS, NULL},
  2692. {"get", (PyCFunction)map_py_get, METH_VARARGS, NULL},
  2693. {"delete", (PyCFunction)map_py_delete, METH_O, NULL},
  2694. {"mutate", (PyCFunction)map_py_mutate, METH_NOARGS, NULL},
  2695. {"items", (PyCFunction)map_py_items, METH_NOARGS, NULL},
  2696. {"keys", (PyCFunction)map_py_keys, METH_NOARGS, NULL},
  2697. {"values", (PyCFunction)map_py_values, METH_NOARGS, NULL},
  2698. {"update", (PyCFunction)map_py_update, METH_VARARGS | METH_KEYWORDS, NULL},
  2699. {"__reduce__", (PyCFunction)map_reduce, METH_NOARGS, NULL},
  2700. {"__dump__", (PyCFunction)map_py_dump, METH_NOARGS, NULL},
  2701. {
  2702. "__class_getitem__",
  2703. (PyCFunction)map_py_class_getitem,
  2704. METH_O|METH_CLASS,
  2705. NULL
  2706. },
  2707. {NULL, NULL}
  2708. };
  2709. static PySequenceMethods Map_as_sequence = {
  2710. 0, /* sq_length */
  2711. 0, /* sq_concat */
  2712. 0, /* sq_repeat */
  2713. 0, /* sq_item */
  2714. 0, /* sq_slice */
  2715. 0, /* sq_ass_item */
  2716. 0, /* sq_ass_slice */
  2717. (objobjproc)map_tp_contains, /* sq_contains */
  2718. 0, /* sq_inplace_concat */
  2719. 0, /* sq_inplace_repeat */
  2720. };
  2721. static PyMappingMethods Map_as_mapping = {
  2722. (lenfunc)map_tp_len, /* mp_length */
  2723. (binaryfunc)map_tp_subscript, /* mp_subscript */
  2724. };
  2725. PyTypeObject _Map_Type = {
  2726. PyVarObject_HEAD_INIT(NULL, 0)
  2727. "immutables._map.Map",
  2728. sizeof(MapObject),
  2729. .tp_methods = Map_methods,
  2730. .tp_as_mapping = &Map_as_mapping,
  2731. .tp_as_sequence = &Map_as_sequence,
  2732. .tp_iter = (getiterfunc)map_tp_iter,
  2733. .tp_dealloc = (destructor)map_tp_dealloc,
  2734. .tp_getattro = PyObject_GenericGetAttr,
  2735. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  2736. .tp_richcompare = map_tp_richcompare,
  2737. .tp_traverse = (traverseproc)map_tp_traverse,
  2738. .tp_clear = (inquiry)map_tp_clear,
  2739. .tp_new = map_tp_new,
  2740. .tp_init = (initproc)map_tp_init,
  2741. .tp_weaklistoffset = offsetof(MapObject, h_weakreflist),
  2742. .tp_hash = (hashfunc)map_py_hash,
  2743. .tp_repr = (reprfunc)map_py_repr,
  2744. };
  2745. /////////////////////////////////// MapMutation
  2746. static int
  2747. map_node_update_from_map(uint64_t mutid,
  2748. MapObject *map,
  2749. MapNode *root, Py_ssize_t count,
  2750. MapNode **new_root, Py_ssize_t *new_count)
  2751. {
  2752. assert(Map_Check(map));
  2753. MapIteratorState iter;
  2754. map_iter_t iter_res;
  2755. MapNode *last_root;
  2756. Py_ssize_t last_count;
  2757. Py_INCREF(root);
  2758. last_root = root;
  2759. last_count = count;
  2760. map_iterator_init(&iter, map->h_root);
  2761. do {
  2762. PyObject *key;
  2763. PyObject *val;
  2764. int32_t key_hash;
  2765. int added_leaf;
  2766. iter_res = map_iterator_next(&iter, &key, &val);
  2767. if (iter_res == I_ITEM) {
  2768. key_hash = map_hash(key);
  2769. if (key_hash == -1) {
  2770. goto err;
  2771. }
  2772. MapNode *iter_root = map_node_assoc(
  2773. last_root,
  2774. 0, key_hash, key, val, &added_leaf,
  2775. mutid);
  2776. if (iter_root == NULL) {
  2777. goto err;
  2778. }
  2779. if (added_leaf) {
  2780. last_count++;
  2781. }
  2782. Py_SETREF(last_root, iter_root);
  2783. }
  2784. } while (iter_res != I_END);
  2785. *new_root = last_root;
  2786. *new_count = last_count;
  2787. return 0;
  2788. err:
  2789. Py_DECREF(last_root);
  2790. return -1;
  2791. }
  2792. static int
  2793. map_node_update_from_dict(uint64_t mutid,
  2794. PyObject *dct,
  2795. MapNode *root, Py_ssize_t count,
  2796. MapNode **new_root, Py_ssize_t *new_count)
  2797. {
  2798. assert(PyDict_Check(dct));
  2799. PyObject *it = PyObject_GetIter(dct);
  2800. if (it == NULL) {
  2801. return -1;
  2802. }
  2803. MapNode *last_root;
  2804. Py_ssize_t last_count;
  2805. Py_INCREF(root);
  2806. last_root = root;
  2807. last_count = count;
  2808. PyObject *key;
  2809. while ((key = PyIter_Next(it))) {
  2810. PyObject *val;
  2811. int added_leaf;
  2812. int32_t key_hash;
  2813. key_hash = map_hash(key);
  2814. if (key_hash == -1) {
  2815. Py_DECREF(key);
  2816. goto err;
  2817. }
  2818. val = PyDict_GetItemWithError(dct, key);
  2819. if (val == NULL) {
  2820. Py_DECREF(key);
  2821. goto err;
  2822. }
  2823. MapNode *iter_root = map_node_assoc(
  2824. last_root,
  2825. 0, key_hash, key, val, &added_leaf,
  2826. mutid);
  2827. Py_DECREF(key);
  2828. if (iter_root == NULL) {
  2829. goto err;
  2830. }
  2831. if (added_leaf) {
  2832. last_count++;
  2833. }
  2834. Py_SETREF(last_root, iter_root);
  2835. }
  2836. if (key == NULL && PyErr_Occurred()) {
  2837. goto err;
  2838. }
  2839. Py_DECREF(it);
  2840. *new_root = last_root;
  2841. *new_count = last_count;
  2842. return 0;
  2843. err:
  2844. Py_DECREF(it);
  2845. Py_DECREF(last_root);
  2846. return -1;
  2847. }
  2848. static int
  2849. map_node_update_from_seq(uint64_t mutid,
  2850. PyObject *seq,
  2851. MapNode *root, Py_ssize_t count,
  2852. MapNode **new_root, Py_ssize_t *new_count)
  2853. {
  2854. PyObject *it;
  2855. Py_ssize_t i;
  2856. PyObject *item = NULL;
  2857. PyObject *fast = NULL;
  2858. MapNode *last_root;
  2859. Py_ssize_t last_count;
  2860. it = PyObject_GetIter(seq);
  2861. if (it == NULL) {
  2862. return -1;
  2863. }
  2864. Py_INCREF(root);
  2865. last_root = root;
  2866. last_count = count;
  2867. for (i = 0; ; i++) {
  2868. PyObject *key, *val;
  2869. Py_ssize_t n;
  2870. int32_t key_hash;
  2871. int added_leaf;
  2872. item = PyIter_Next(it);
  2873. if (item == NULL) {
  2874. if (PyErr_Occurred()) {
  2875. goto err;
  2876. }
  2877. break;
  2878. }
  2879. fast = PySequence_Fast(item, "");
  2880. if (fast == NULL) {
  2881. if (PyErr_ExceptionMatches(PyExc_TypeError))
  2882. PyErr_Format(PyExc_TypeError,
  2883. "cannot convert map update "
  2884. "sequence element #%zd to a sequence",
  2885. i);
  2886. goto err;
  2887. }
  2888. n = PySequence_Fast_GET_SIZE(fast);
  2889. if (n != 2) {
  2890. PyErr_Format(PyExc_ValueError,
  2891. "map update sequence element #%zd "
  2892. "has length %zd; 2 is required",
  2893. i, n);
  2894. goto err;
  2895. }
  2896. key = PySequence_Fast_GET_ITEM(fast, 0);
  2897. val = PySequence_Fast_GET_ITEM(fast, 1);
  2898. Py_INCREF(key);
  2899. Py_INCREF(val);
  2900. key_hash = map_hash(key);
  2901. if (key_hash == -1) {
  2902. Py_DECREF(key);
  2903. Py_DECREF(val);
  2904. goto err;
  2905. }
  2906. MapNode *iter_root = map_node_assoc(
  2907. last_root,
  2908. 0, key_hash, key, val, &added_leaf,
  2909. mutid);
  2910. Py_DECREF(key);
  2911. Py_DECREF(val);
  2912. if (iter_root == NULL) {
  2913. goto err;
  2914. }
  2915. if (added_leaf) {
  2916. last_count++;
  2917. }
  2918. Py_SETREF(last_root, iter_root);
  2919. Py_DECREF(fast);
  2920. Py_DECREF(item);
  2921. }
  2922. Py_DECREF(it);
  2923. *new_root = last_root;
  2924. *new_count = last_count;
  2925. return 0;
  2926. err:
  2927. Py_DECREF(last_root);
  2928. Py_XDECREF(item);
  2929. Py_XDECREF(fast);
  2930. Py_DECREF(it);
  2931. return -1;
  2932. }
  2933. static int
  2934. map_node_update(uint64_t mutid,
  2935. PyObject *src,
  2936. MapNode *root, Py_ssize_t count,
  2937. MapNode **new_root, Py_ssize_t *new_count)
  2938. {
  2939. if (Map_Check(src)) {
  2940. return map_node_update_from_map(
  2941. mutid, (MapObject *)src, root, count, new_root, new_count);
  2942. }
  2943. else if (PyDict_Check(src)) {
  2944. return map_node_update_from_dict(
  2945. mutid, src, root, count, new_root, new_count);
  2946. }
  2947. else {
  2948. return map_node_update_from_seq(
  2949. mutid, src, root, count, new_root, new_count);
  2950. }
  2951. }
  2952. static int
  2953. map_update_inplace(uint64_t mutid, BaseMapObject *o, PyObject *src)
  2954. {
  2955. MapNode *new_root = NULL;
  2956. Py_ssize_t new_count;
  2957. int ret = map_node_update(
  2958. mutid, src,
  2959. o->b_root, o->b_count,
  2960. &new_root, &new_count);
  2961. if (ret) {
  2962. return -1;
  2963. }
  2964. assert(new_root);
  2965. Py_SETREF(o->b_root, new_root);
  2966. o->b_count = new_count;
  2967. return 0;
  2968. }
  2969. static MapObject *
  2970. map_update(uint64_t mutid, MapObject *o, PyObject *src)
  2971. {
  2972. MapNode *new_root = NULL;
  2973. Py_ssize_t new_count;
  2974. int ret = map_node_update(
  2975. mutid, src,
  2976. o->h_root, o->h_count,
  2977. &new_root, &new_count);
  2978. if (ret) {
  2979. return NULL;
  2980. }
  2981. assert(new_root);
  2982. MapObject *new = map_alloc();
  2983. if (new == NULL) {
  2984. Py_DECREF(new_root);
  2985. return NULL;
  2986. }
  2987. Py_XSETREF(new->h_root, new_root);
  2988. new->h_count = new_count;
  2989. return new;
  2990. }
  2991. static int
  2992. mapmut_check_finalized(MapMutationObject *o)
  2993. {
  2994. if (o->m_mutid == 0) {
  2995. PyErr_Format(
  2996. PyExc_ValueError,
  2997. "mutation %R has been finished",
  2998. o, NULL);
  2999. return -1;
  3000. }
  3001. return 0;
  3002. }
  3003. static int
  3004. mapmut_delete(MapMutationObject *o, PyObject *key, int32_t key_hash)
  3005. {
  3006. MapNode *new_root = NULL;
  3007. assert(key_hash != -1);
  3008. map_without_t res = map_node_without(
  3009. (MapNode *)(o->m_root),
  3010. 0, key_hash, key,
  3011. &new_root,
  3012. o->m_mutid);
  3013. switch (res) {
  3014. case W_ERROR:
  3015. return -1;
  3016. case W_EMPTY:
  3017. new_root = map_node_bitmap_new(0, o->m_mutid);
  3018. if (new_root == NULL) {
  3019. return -1;
  3020. }
  3021. Py_SETREF(o->m_root, new_root);
  3022. o->m_count = 0;
  3023. return 0;
  3024. case W_NOT_FOUND:
  3025. PyErr_SetObject(PyExc_KeyError, key);
  3026. return -1;
  3027. case W_NEWNODE: {
  3028. assert(new_root != NULL);
  3029. Py_SETREF(o->m_root, new_root);
  3030. o->m_count--;
  3031. return 0;
  3032. }
  3033. default:
  3034. abort();
  3035. }
  3036. }
  3037. static int
  3038. mapmut_set(MapMutationObject *o, PyObject *key, int32_t key_hash,
  3039. PyObject *val)
  3040. {
  3041. int added_leaf = 0;
  3042. assert(key_hash != -1);
  3043. MapNode *new_root = map_node_assoc(
  3044. (MapNode *)(o->m_root),
  3045. 0, key_hash, key, val, &added_leaf,
  3046. o->m_mutid);
  3047. if (new_root == NULL) {
  3048. return -1;
  3049. }
  3050. if (added_leaf) {
  3051. o->m_count++;
  3052. }
  3053. if (new_root == o->m_root) {
  3054. Py_DECREF(new_root);
  3055. return 0;
  3056. }
  3057. Py_SETREF(o->m_root, new_root);
  3058. return 0;
  3059. }
  3060. static int
  3061. mapmut_finish(MapMutationObject *o)
  3062. {
  3063. o->m_mutid = 0;
  3064. return 0;
  3065. }
  3066. static PyObject *
  3067. mapmut_py_set(MapMutationObject *o, PyObject *args)
  3068. {
  3069. PyObject *key;
  3070. PyObject *val;
  3071. if (!PyArg_UnpackTuple(args, "set", 2, 2, &key, &val)) {
  3072. return NULL;
  3073. }
  3074. if (mapmut_check_finalized(o)) {
  3075. return NULL;
  3076. }
  3077. int32_t key_hash = map_hash(key);
  3078. if (key_hash == -1) {
  3079. return NULL;
  3080. }
  3081. if (mapmut_set(o, key, key_hash, val)) {
  3082. return NULL;
  3083. }
  3084. Py_RETURN_NONE;
  3085. }
  3086. static PyObject *
  3087. mapmut_tp_richcompare(PyObject *v, PyObject *w, int op)
  3088. {
  3089. if (!MapMutation_Check(v) || !MapMutation_Check(w) ||
  3090. (op != Py_EQ && op != Py_NE))
  3091. {
  3092. Py_RETURN_NOTIMPLEMENTED;
  3093. }
  3094. int res = map_eq((BaseMapObject *)v, (BaseMapObject *)w);
  3095. if (res < 0) {
  3096. return NULL;
  3097. }
  3098. if (op == Py_NE) {
  3099. res = !res;
  3100. }
  3101. if (res) {
  3102. Py_RETURN_TRUE;
  3103. }
  3104. else {
  3105. Py_RETURN_FALSE;
  3106. }
  3107. }
  3108. static PyObject *
  3109. mapmut_py_update(MapMutationObject *self, PyObject *args, PyObject *kwds)
  3110. {
  3111. PyObject *arg = NULL;
  3112. if (!PyArg_UnpackTuple(args, "update", 0, 1, &arg)) {
  3113. return NULL;
  3114. }
  3115. if (mapmut_check_finalized(self)) {
  3116. return NULL;
  3117. }
  3118. if (arg != NULL) {
  3119. if (map_update_inplace(self->m_mutid, (BaseMapObject *)self, arg)) {
  3120. return NULL;
  3121. }
  3122. }
  3123. if (kwds != NULL) {
  3124. if (!PyArg_ValidateKeywordArguments(kwds)) {
  3125. return NULL;
  3126. }
  3127. if (map_update_inplace(self->m_mutid, (BaseMapObject *)self, kwds)) {
  3128. return NULL;
  3129. }
  3130. }
  3131. Py_RETURN_NONE;
  3132. }
  3133. static PyObject *
  3134. mapmut_py_finish(MapMutationObject *self, PyObject *args)
  3135. {
  3136. if (mapmut_finish(self)) {
  3137. return NULL;
  3138. }
  3139. MapObject *o = map_alloc();
  3140. if (o == NULL) {
  3141. return NULL;
  3142. }
  3143. Py_INCREF(self->m_root);
  3144. o->h_root = self->m_root;
  3145. o->h_count = self->m_count;
  3146. return (PyObject *)o;
  3147. }
  3148. static PyObject *
  3149. mapmut_py_enter(MapMutationObject *self, PyObject *args)
  3150. {
  3151. Py_INCREF(self);
  3152. return (PyObject *)self;
  3153. }
  3154. static PyObject *
  3155. mapmut_py_exit(MapMutationObject *self, PyObject *args)
  3156. {
  3157. if (mapmut_finish(self)) {
  3158. return NULL;
  3159. }
  3160. Py_RETURN_FALSE;
  3161. }
  3162. static int
  3163. mapmut_tp_ass_sub(MapMutationObject *self, PyObject *key, PyObject *val)
  3164. {
  3165. if (mapmut_check_finalized(self)) {
  3166. return -1;
  3167. }
  3168. int32_t key_hash = map_hash(key);
  3169. if (key_hash == -1) {
  3170. return -1;
  3171. }
  3172. if (val == NULL) {
  3173. return mapmut_delete(self, key, key_hash);
  3174. }
  3175. else {
  3176. return mapmut_set(self, key, key_hash, val);
  3177. }
  3178. }
  3179. static PyObject *
  3180. mapmut_py_pop(MapMutationObject *self, PyObject *args)
  3181. {
  3182. PyObject *key, *deflt = NULL, *val = NULL;
  3183. if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) {
  3184. return NULL;
  3185. }
  3186. if (mapmut_check_finalized(self)) {
  3187. return NULL;
  3188. }
  3189. if (!self->m_count) {
  3190. goto not_found;
  3191. }
  3192. int32_t key_hash = map_hash(key);
  3193. if (key_hash == -1) {
  3194. return NULL;
  3195. }
  3196. map_find_t find_res = map_node_find(self->m_root, 0, key_hash, key, &val);
  3197. switch (find_res) {
  3198. case F_ERROR:
  3199. return NULL;
  3200. case F_NOT_FOUND:
  3201. goto not_found;
  3202. case F_FOUND:
  3203. break;
  3204. default:
  3205. abort();
  3206. }
  3207. Py_INCREF(val);
  3208. if (mapmut_delete(self, key, key_hash)) {
  3209. Py_DECREF(val);
  3210. return NULL;
  3211. }
  3212. return val;
  3213. not_found:
  3214. if (deflt) {
  3215. Py_INCREF(deflt);
  3216. return deflt;
  3217. }
  3218. PyErr_SetObject(PyExc_KeyError, key);
  3219. return NULL;
  3220. }
  3221. static PyMethodDef MapMutation_methods[] = {
  3222. {"set", (PyCFunction)mapmut_py_set, METH_VARARGS, NULL},
  3223. {"get", (PyCFunction)map_py_get, METH_VARARGS, NULL},
  3224. {"pop", (PyCFunction)mapmut_py_pop, METH_VARARGS, NULL},
  3225. {"finish", (PyCFunction)mapmut_py_finish, METH_NOARGS, NULL},
  3226. {"update", (PyCFunction)mapmut_py_update,
  3227. METH_VARARGS | METH_KEYWORDS, NULL},
  3228. {"__enter__", (PyCFunction)mapmut_py_enter, METH_NOARGS, NULL},
  3229. {"__exit__", (PyCFunction)mapmut_py_exit, METH_VARARGS, NULL},
  3230. {NULL, NULL}
  3231. };
  3232. static PySequenceMethods MapMutation_as_sequence = {
  3233. 0, /* sq_length */
  3234. 0, /* sq_concat */
  3235. 0, /* sq_repeat */
  3236. 0, /* sq_item */
  3237. 0, /* sq_slice */
  3238. 0, /* sq_ass_item */
  3239. 0, /* sq_ass_slice */
  3240. (objobjproc)map_tp_contains, /* sq_contains */
  3241. 0, /* sq_inplace_concat */
  3242. 0, /* sq_inplace_repeat */
  3243. };
  3244. static PyMappingMethods MapMutation_as_mapping = {
  3245. (lenfunc)map_tp_len, /* mp_length */
  3246. (binaryfunc)map_tp_subscript, /* mp_subscript */
  3247. (objobjargproc)mapmut_tp_ass_sub, /* mp_subscript */
  3248. };
  3249. PyTypeObject _MapMutation_Type = {
  3250. PyVarObject_HEAD_INIT(NULL, 0)
  3251. "immutables._map.MapMutation",
  3252. sizeof(MapMutationObject),
  3253. .tp_methods = MapMutation_methods,
  3254. .tp_as_mapping = &MapMutation_as_mapping,
  3255. .tp_as_sequence = &MapMutation_as_sequence,
  3256. .tp_dealloc = (destructor)map_tp_dealloc,
  3257. .tp_getattro = PyObject_GenericGetAttr,
  3258. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  3259. .tp_traverse = (traverseproc)map_tp_traverse,
  3260. .tp_richcompare = mapmut_tp_richcompare,
  3261. .tp_clear = (inquiry)map_tp_clear,
  3262. .tp_weaklistoffset = offsetof(MapMutationObject, m_weakreflist),
  3263. .tp_repr = (reprfunc)map_py_repr,
  3264. .tp_hash = PyObject_HashNotImplemented,
  3265. };
  3266. /////////////////////////////////// Tree Node Types
  3267. PyTypeObject _Map_ArrayNode_Type = {
  3268. PyVarObject_HEAD_INIT(NULL, 0)
  3269. "map_array_node",
  3270. sizeof(MapNode_Array),
  3271. 0,
  3272. .tp_dealloc = (destructor)map_node_array_dealloc,
  3273. .tp_getattro = PyObject_GenericGetAttr,
  3274. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  3275. .tp_traverse = (traverseproc)map_node_array_traverse,
  3276. .tp_free = PyObject_GC_Del,
  3277. .tp_hash = PyObject_HashNotImplemented,
  3278. };
  3279. PyTypeObject _Map_BitmapNode_Type = {
  3280. PyVarObject_HEAD_INIT(NULL, 0)
  3281. "map_bitmap_node",
  3282. sizeof(MapNode_Bitmap) - sizeof(PyObject *),
  3283. sizeof(PyObject *),
  3284. .tp_dealloc = (destructor)map_node_bitmap_dealloc,
  3285. .tp_getattro = PyObject_GenericGetAttr,
  3286. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  3287. .tp_traverse = (traverseproc)map_node_bitmap_traverse,
  3288. .tp_free = PyObject_GC_Del,
  3289. .tp_hash = PyObject_HashNotImplemented,
  3290. };
  3291. PyTypeObject _Map_CollisionNode_Type = {
  3292. PyVarObject_HEAD_INIT(NULL, 0)
  3293. "map_collision_node",
  3294. sizeof(MapNode_Collision) - sizeof(PyObject *),
  3295. sizeof(PyObject *),
  3296. .tp_dealloc = (destructor)map_node_collision_dealloc,
  3297. .tp_getattro = PyObject_GenericGetAttr,
  3298. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  3299. .tp_traverse = (traverseproc)map_node_collision_traverse,
  3300. .tp_free = PyObject_GC_Del,
  3301. .tp_hash = PyObject_HashNotImplemented,
  3302. };
  3303. static void
  3304. module_free(void *m)
  3305. {
  3306. Py_CLEAR(_empty_bitmap_node);
  3307. }
  3308. static struct PyModuleDef _mapmodule = {
  3309. PyModuleDef_HEAD_INIT, /* m_base */
  3310. "_map", /* m_name */
  3311. NULL, /* m_doc */
  3312. -1, /* m_size */
  3313. NULL, /* m_methods */
  3314. NULL, /* m_slots */
  3315. NULL, /* m_traverse */
  3316. NULL, /* m_clear */
  3317. module_free, /* m_free */
  3318. };
  3319. PyMODINIT_FUNC
  3320. PyInit__map(void)
  3321. {
  3322. PyObject *m = PyModule_Create(&_mapmodule);
  3323. if ((PyType_Ready(&_Map_Type) < 0) ||
  3324. (PyType_Ready(&_MapMutation_Type) < 0) ||
  3325. (PyType_Ready(&_Map_ArrayNode_Type) < 0) ||
  3326. (PyType_Ready(&_Map_BitmapNode_Type) < 0) ||
  3327. (PyType_Ready(&_Map_CollisionNode_Type) < 0) ||
  3328. (PyType_Ready(&_MapKeys_Type) < 0) ||
  3329. (PyType_Ready(&_MapValues_Type) < 0) ||
  3330. (PyType_Ready(&_MapItems_Type) < 0) ||
  3331. (PyType_Ready(&_MapKeysIter_Type) < 0) ||
  3332. (PyType_Ready(&_MapValuesIter_Type) < 0) ||
  3333. (PyType_Ready(&_MapItemsIter_Type) < 0))
  3334. {
  3335. return 0;
  3336. }
  3337. Py_INCREF(&_Map_Type);
  3338. if (PyModule_AddObject(m, "Map", (PyObject *)&_Map_Type) < 0) {
  3339. Py_DECREF(&_Map_Type);
  3340. return NULL;
  3341. }
  3342. return m;
  3343. }