annotate Modules/hashtable.c @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents 6e2089dbc5ad
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
87401
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
1 /* The implementation of the hash table (_Py_hashtable_t) is based on the cfuhash
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
2 project:
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
3 http://sourceforge.net/projects/libcfu/
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
4
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
5 Copyright of cfuhash:
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
6 ----------------------------------
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
7 Creation date: 2005-06-24 21:22:40
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
8 Authors: Don
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
9 Change log:
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
10
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
11 Copyright (c) 2005 Don Owens
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
12 All rights reserved.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
13
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
14 This code is released under the BSD license:
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
15
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
16 Redistribution and use in source and binary forms, with or without
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
17 modification, are permitted provided that the following conditions
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
18 are met:
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
19
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
20 * Redistributions of source code must retain the above copyright
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
21 notice, this list of conditions and the following disclaimer.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
22
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
23 * Redistributions in binary form must reproduce the above
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
24 copyright notice, this list of conditions and the following
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
25 disclaimer in the documentation and/or other materials provided
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
26 with the distribution.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
27
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
28 * Neither the name of the author nor the names of its
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
29 contributors may be used to endorse or promote products derived
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
30 from this software without specific prior written permission.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
31
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
33 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
34 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
35 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
36 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
37 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
38 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
39 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
40 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
41 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
42 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
43 OF THE POSSIBILITY OF SUCH DAMAGE.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
44 ----------------------------------
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
45 */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
46
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
47 #include "Python.h"
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
48 #include "hashtable.h"
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
49
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
50 #define HASHTABLE_MIN_SIZE 16
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
51 #define HASHTABLE_HIGH 0.50
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
52 #define HASHTABLE_LOW 0.10
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
53 #define HASHTABLE_REHASH_FACTOR 2.0 / (HASHTABLE_LOW + HASHTABLE_HIGH)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
54
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
55 #define BUCKETS_HEAD(SLIST) \
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
56 ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(SLIST)))
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
57 #define TABLE_HEAD(HT, BUCKET) \
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
58 ((_Py_hashtable_entry_t *)_Py_SLIST_HEAD(&(HT)->buckets[BUCKET]))
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
59 #define ENTRY_NEXT(ENTRY) \
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
60 ((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY))
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
61 #define HASHTABLE_ITEM_SIZE(HT) \
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
62 (sizeof(_Py_hashtable_entry_t) + (HT)->data_size)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
63
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
64 /* Forward declaration */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
65 static void hashtable_rehash(_Py_hashtable_t *ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
66
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
67 static void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
68 _Py_slist_init(_Py_slist_t *list)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
69 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
70 list->head = NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
71 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
72
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
73 static void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
74 _Py_slist_prepend(_Py_slist_t *list, _Py_slist_item_t *item)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
75 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
76 item->next = list->head;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
77 list->head = item;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
78 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
79
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
80 static void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
81 _Py_slist_remove(_Py_slist_t *list, _Py_slist_item_t *previous,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
82 _Py_slist_item_t *item)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
83 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
84 if (previous != NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
85 previous->next = item->next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
86 else
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
87 list->head = item->next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
88 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
89
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
90 Py_uhash_t
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
91 _Py_hashtable_hash_int(const void *key)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
92 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
93 return (Py_uhash_t)key;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
94 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
95
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
96 Py_uhash_t
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
97 _Py_hashtable_hash_ptr(const void *key)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
98 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
99 return (Py_uhash_t)_Py_HashPointer((void *)key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
100 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
101
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
102 int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
103 _Py_hashtable_compare_direct(const void *key, const _Py_hashtable_entry_t *entry)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
104 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
105 return entry->key == key;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
106 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
107
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
108 /* makes sure the real size of the buckets array is a power of 2 */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
109 static size_t
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
110 round_size(size_t s)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
111 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
112 size_t i;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
113 if (s < HASHTABLE_MIN_SIZE)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
114 return HASHTABLE_MIN_SIZE;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
115 i = 1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
116 while (i < s)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
117 i <<= 1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
118 return i;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
119 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
120
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
121 _Py_hashtable_t *
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
122 _Py_hashtable_new_full(size_t data_size, size_t init_size,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
123 _Py_hashtable_hash_func hash_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
124 _Py_hashtable_compare_func compare_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
125 _Py_hashtable_copy_data_func copy_data_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
126 _Py_hashtable_free_data_func free_data_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
127 _Py_hashtable_get_data_size_func get_data_size_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
128 _Py_hashtable_allocator_t *allocator)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
129 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
130 _Py_hashtable_t *ht;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
131 size_t buckets_size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
132 _Py_hashtable_allocator_t alloc;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
133
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
134 if (allocator == NULL) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
135 alloc.malloc = PyMem_RawMalloc;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
136 alloc.free = PyMem_RawFree;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
137 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
138 else
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
139 alloc = *allocator;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
140
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
141 ht = (_Py_hashtable_t *)alloc.malloc(sizeof(_Py_hashtable_t));
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
142 if (ht == NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
143 return ht;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
144
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
145 ht->num_buckets = round_size(init_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
146 ht->entries = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
147 ht->data_size = data_size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
148
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
149 buckets_size = ht->num_buckets * sizeof(ht->buckets[0]);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
150 ht->buckets = alloc.malloc(buckets_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
151 if (ht->buckets == NULL) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
152 alloc.free(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
153 return NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
154 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
155 memset(ht->buckets, 0, buckets_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
156
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
157 ht->hash_func = hash_func;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
158 ht->compare_func = compare_func;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
159 ht->copy_data_func = copy_data_func;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
160 ht->free_data_func = free_data_func;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
161 ht->get_data_size_func = get_data_size_func;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
162 ht->alloc = alloc;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
163 return ht;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
164 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
165
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
166 _Py_hashtable_t *
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
167 _Py_hashtable_new(size_t data_size,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
168 _Py_hashtable_hash_func hash_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
169 _Py_hashtable_compare_func compare_func)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
170 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
171 return _Py_hashtable_new_full(data_size, HASHTABLE_MIN_SIZE,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
172 hash_func, compare_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
173 NULL, NULL, NULL, NULL);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
174 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
175
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
176 size_t
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
177 _Py_hashtable_size(_Py_hashtable_t *ht)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
178 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
179 size_t size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
180 size_t hv;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
181
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
182 size = sizeof(_Py_hashtable_t);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
183
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
184 /* buckets */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
185 size += ht->num_buckets * sizeof(_Py_hashtable_entry_t *);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
186
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
187 /* entries */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
188 size += ht->entries * HASHTABLE_ITEM_SIZE(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
189
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
190 /* data linked from entries */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
191 if (ht->get_data_size_func) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
192 for (hv = 0; hv < ht->num_buckets; hv++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
193 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
194
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
195 for (entry = TABLE_HEAD(ht, hv); entry; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
196 void *data;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
197
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
198 data = _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
199 size += ht->get_data_size_func(data);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
200 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
201 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
202 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
203 return size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
204 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
205
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
206 #ifdef Py_DEBUG
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
207 void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
208 _Py_hashtable_print_stats(_Py_hashtable_t *ht)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
209 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
210 size_t size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
211 size_t chain_len, max_chain_len, total_chain_len, nchains;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
212 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
213 size_t hv;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
214 double load;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
215
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
216 size = _Py_hashtable_size(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
217
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
218 load = (double)ht->entries / ht->num_buckets;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
219
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
220 max_chain_len = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
221 total_chain_len = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
222 nchains = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
223 for (hv = 0; hv < ht->num_buckets; hv++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
224 entry = TABLE_HEAD(ht, hv);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
225 if (entry != NULL) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
226 chain_len = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
227 for (; entry; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
228 chain_len++;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
229 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
230 if (chain_len > max_chain_len)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
231 max_chain_len = chain_len;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
232 total_chain_len += chain_len;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
233 nchains++;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
234 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
235 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
236 printf("hash table %p: entries=%zu/%zu (%.0f%%), ",
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
237 ht, ht->entries, ht->num_buckets, load * 100.0);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
238 if (nchains)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
239 printf("avg_chain_len=%.1f, ", (double)total_chain_len / nchains);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
240 printf("max_chain_len=%zu, %zu kB\n",
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
241 max_chain_len, size / 1024);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
242 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
243 #endif
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
244
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
245 /* Get an entry. Return NULL if the key does not exist. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
246 _Py_hashtable_entry_t *
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
247 _Py_hashtable_get_entry(_Py_hashtable_t *ht, const void *key)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
248 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
249 Py_uhash_t key_hash;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
250 size_t index;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
251 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
252
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
253 key_hash = ht->hash_func(key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
254 index = key_hash & (ht->num_buckets - 1);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
255
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
256 for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
257 if (entry->key_hash == key_hash && ht->compare_func(key, entry))
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
258 break;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
259 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
260
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
261 return entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
262 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
263
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
264 static int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
265 _hashtable_pop_entry(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
266 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
267 Py_uhash_t key_hash;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
268 size_t index;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
269 _Py_hashtable_entry_t *entry, *previous;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
270
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
271 key_hash = ht->hash_func(key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
272 index = key_hash & (ht->num_buckets - 1);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
273
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
274 previous = NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
275 for (entry = TABLE_HEAD(ht, index); entry != NULL; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
276 if (entry->key_hash == key_hash && ht->compare_func(key, entry))
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
277 break;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
278 previous = entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
279 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
280
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
281 if (entry == NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
282 return 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
283
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
284 _Py_slist_remove(&ht->buckets[index], (_Py_slist_item_t *)previous,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
285 (_Py_slist_item_t *)entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
286 ht->entries--;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
287
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
288 if (data != NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
289 _Py_HASHTABLE_ENTRY_READ_DATA(ht, data, data_size, entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
290 ht->alloc.free(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
291
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
292 if ((float)ht->entries / (float)ht->num_buckets < HASHTABLE_LOW)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
293 hashtable_rehash(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
294 return 1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
295 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
296
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
297 /* Add a new entry to the hash. The key must not be present in the hash table.
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
298 Return 0 on success, -1 on memory error. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
299 int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
300 _Py_hashtable_set(_Py_hashtable_t *ht, const void *key,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
301 void *data, size_t data_size)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
302 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
303 Py_uhash_t key_hash;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
304 size_t index;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
305 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
306
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
307 assert(data != NULL || data_size == 0);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
308 #ifndef NDEBUG
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
309 /* Don't write the assertion on a single line because it is interesting
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
310 to know the duplicated entry if the assertion failed. The entry can
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
311 be read using a debugger. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
312 entry = _Py_hashtable_get_entry(ht, key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
313 assert(entry == NULL);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
314 #endif
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
315
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
316 key_hash = ht->hash_func(key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
317 index = key_hash & (ht->num_buckets - 1);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
318
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
319 entry = ht->alloc.malloc(HASHTABLE_ITEM_SIZE(ht));
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
320 if (entry == NULL) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
321 /* memory allocation failed */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
322 return -1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
323 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
324
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
325 entry->key = (void *)key;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
326 entry->key_hash = key_hash;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
327
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
328 assert(data_size == ht->data_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
329 memcpy(_PY_HASHTABLE_ENTRY_DATA(entry), data, data_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
330
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
331 _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
332 ht->entries++;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
333
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
334 if ((float)ht->entries / (float)ht->num_buckets > HASHTABLE_HIGH)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
335 hashtable_rehash(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
336 return 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
337 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
338
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
339 /* Get data from an entry. Copy entry data into data and return 1 if the entry
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
340 exists, return 0 if the entry does not exist. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
341 int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
342 _Py_hashtable_get(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
343 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
344 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
345
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
346 assert(data != NULL);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
347
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
348 entry = _Py_hashtable_get_entry(ht, key);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
349 if (entry == NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
350 return 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
351 _Py_HASHTABLE_ENTRY_READ_DATA(ht, data, data_size, entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
352 return 1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
353 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
354
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
355 int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
356 _Py_hashtable_pop(_Py_hashtable_t *ht, const void *key, void *data, size_t data_size)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
357 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
358 assert(data != NULL);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
359 assert(ht->free_data_func == NULL);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
360 return _hashtable_pop_entry(ht, key, data, data_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
361 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
362
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
363 /* Delete an entry. The entry must exist. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
364 void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
365 _Py_hashtable_delete(_Py_hashtable_t *ht, const void *key)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
366 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
367 #ifndef NDEBUG
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
368 int found = _hashtable_pop_entry(ht, key, NULL, 0);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
369 assert(found);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
370 #else
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
371 (void)_hashtable_pop_entry(ht, key, NULL, 0);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
372 #endif
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
373 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
374
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
375 /* Prototype for a pointer to a function to be called foreach
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
376 key/value pair in the hash by hashtable_foreach(). Iteration
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
377 stops if a non-zero value is returned. */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
378 int
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
379 _Py_hashtable_foreach(_Py_hashtable_t *ht,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
380 int (*func) (_Py_hashtable_entry_t *entry, void *arg),
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
381 void *arg)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
382 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
383 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
384 size_t hv;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
385
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
386 for (hv = 0; hv < ht->num_buckets; hv++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
387 for (entry = TABLE_HEAD(ht, hv); entry; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
388 int res = func(entry, arg);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
389 if (res)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
390 return res;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
391 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
392 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
393 return 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
394 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
395
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
396 static void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
397 hashtable_rehash(_Py_hashtable_t *ht)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
398 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
399 size_t buckets_size, new_size, bucket;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
400 _Py_slist_t *old_buckets = NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
401 size_t old_num_buckets;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
402
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
403 new_size = round_size((size_t)(ht->entries * HASHTABLE_REHASH_FACTOR));
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
404 if (new_size == ht->num_buckets)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
405 return;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
406
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
407 old_num_buckets = ht->num_buckets;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
408
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
409 buckets_size = new_size * sizeof(ht->buckets[0]);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
410 old_buckets = ht->buckets;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
411 ht->buckets = ht->alloc.malloc(buckets_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
412 if (ht->buckets == NULL) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
413 /* cancel rehash on memory allocation failure */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
414 ht->buckets = old_buckets ;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
415 /* memory allocation failed */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
416 return;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
417 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
418 memset(ht->buckets, 0, buckets_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
419
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
420 ht->num_buckets = new_size;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
421
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
422 for (bucket = 0; bucket < old_num_buckets; bucket++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
423 _Py_hashtable_entry_t *entry, *next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
424 for (entry = BUCKETS_HEAD(old_buckets[bucket]); entry != NULL; entry = next) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
425 size_t entry_index;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
426
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
427 assert(ht->hash_func(entry->key) == entry->key_hash);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
428 next = ENTRY_NEXT(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
429 entry_index = entry->key_hash & (new_size - 1);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
430
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
431 _Py_slist_prepend(&ht->buckets[entry_index], (_Py_slist_item_t*)entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
432 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
433 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
434
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
435 ht->alloc.free(old_buckets);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
436 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
437
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
438 void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
439 _Py_hashtable_clear(_Py_hashtable_t *ht)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
440 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
441 _Py_hashtable_entry_t *entry, *next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
442 size_t i;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
443
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
444 for (i=0; i < ht->num_buckets; i++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
445 for (entry = TABLE_HEAD(ht, i); entry != NULL; entry = next) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
446 next = ENTRY_NEXT(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
447 if (ht->free_data_func)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
448 ht->free_data_func(_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry));
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
449 ht->alloc.free(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
450 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
451 _Py_slist_init(&ht->buckets[i]);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
452 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
453 ht->entries = 0;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
454 hashtable_rehash(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
455 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
456
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
457 void
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
458 _Py_hashtable_destroy(_Py_hashtable_t *ht)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
459 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
460 size_t i;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
461
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
462 for (i = 0; i < ht->num_buckets; i++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
463 _Py_slist_item_t *entry = ht->buckets[i].head;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
464 while (entry) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
465 _Py_slist_item_t *entry_next = entry->next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
466 if (ht->free_data_func)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
467 ht->free_data_func(_Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry));
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
468 ht->alloc.free(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
469 entry = entry_next;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
470 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
471 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
472
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
473 ht->alloc.free(ht->buckets);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
474 ht->alloc.free(ht);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
475 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
476
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
477 /* Return a copy of the hash table */
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
478 _Py_hashtable_t *
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
479 _Py_hashtable_copy(_Py_hashtable_t *src)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
480 {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
481 _Py_hashtable_t *dst;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
482 _Py_hashtable_entry_t *entry;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
483 size_t bucket;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
484 int err;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
485 void *data, *new_data;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
486
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
487 dst = _Py_hashtable_new_full(src->data_size, src->num_buckets,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
488 src->hash_func, src->compare_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
489 src->copy_data_func, src->free_data_func,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
490 src->get_data_size_func, &src->alloc);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
491 if (dst == NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
492 return NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
493
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
494 for (bucket=0; bucket < src->num_buckets; bucket++) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
495 entry = TABLE_HEAD(src, bucket);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
496 for (; entry; entry = ENTRY_NEXT(entry)) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
497 if (src->copy_data_func) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
498 data = _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
499 new_data = src->copy_data_func(data);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
500 if (new_data != NULL)
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
501 err = _Py_hashtable_set(dst, entry->key,
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
502 &new_data, src->data_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
503 else
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
504 err = 1;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
505 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
506 else {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
507 data = _PY_HASHTABLE_ENTRY_DATA(entry);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
508 err = _Py_hashtable_set(dst, entry->key, data, src->data_size);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
509 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
510 if (err) {
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
511 _Py_hashtable_destroy(dst);
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
512 return NULL;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
513 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
514 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
515 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
516 return dst;
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
517 }
6e2089dbc5ad Issue #18874: Implement the PEP 454 (tracemalloc)
Victor Stinner <victor.stinner@gmail.com>
parents:
diff changeset
518