Skip to content

Commit b989de6

Browse files
committed
py: allow presizing dicts
1 parent 8b7237b commit b989de6

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

py/map.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,16 @@ void mp_map_clear(mp_map_t *map) {
129129
}
130130

131131
STATIC void mp_map_rehash(mp_map_t *map) {
132-
size_t old_alloc = map->alloc;
133132
size_t new_alloc = get_hash_alloc_greater_or_equal_to(map->alloc + 1);
134-
DEBUG_printf("mp_map_rehash(%p): " UINT_FMT " -> " UINT_FMT "\n", map, old_alloc, new_alloc);
133+
DEBUG_printf("mp_map_rehash(%p): " UINT_FMT " -> " UINT_FMT "\n", map, map->alloc, new_alloc);
134+
mp_map_presize(map, new_alloc);
135+
}
136+
137+
void mp_map_presize(mp_map_t *map, size_t new_alloc) {
138+
size_t old_alloc = map->alloc;
139+
if (new_alloc < old_alloc) {
140+
mp_raise_msg_varg(&mp_type_ValueError, "Map capacity (" UINT_FMT ") must not decrease: " UINT_FMT, old_alloc, new_alloc);
141+
}
135142
mp_map_elem_t *old_table = map->table;
136143
mp_map_elem_t *new_table = m_new0(mp_map_elem_t, new_alloc);
137144
// If we reach this point, table resizing succeeded, now we can edit the old map.

py/obj.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ void mp_map_free(mp_map_t *map);
466466
mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind);
467467
void mp_map_clear(mp_map_t *map);
468468
void mp_map_dump(mp_map_t *map);
469+
void mp_map_presize(mp_map_t *map, size_t n);
469470

470471
// Underlying set implementation (not set object)
471472

@@ -946,6 +947,7 @@ typedef struct _mp_obj_dict_t {
946947
} mp_obj_dict_t;
947948
mp_obj_t mp_obj_dict_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args);
948949
void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args);
950+
void mp_obj_dict_presize(mp_obj_dict_t *dict, size_t n_args);
949951
size_t mp_obj_dict_len(mp_obj_t self_in);
950952
mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index);
951953
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);

py/objdict.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,10 @@ void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args) {
617617
mp_map_init(&dict->map, n_args);
618618
}
619619

620+
void mp_obj_dict_presize(mp_obj_dict_t *dict, size_t n_args) {
621+
mp_map_presize(&dict->map, n_args);
622+
}
623+
620624
mp_obj_t mp_obj_new_dict(size_t n_args) {
621625
mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t);
622626
mp_obj_dict_init(o, n_args);

0 commit comments

Comments
 (0)