Skip to content

Commit d0e8243

Browse files
committed
py: Make mp_map_lookup not allocate memory on removal.
1 parent 09af536 commit d0e8243

File tree

2 files changed

+9
-11
lines changed

2 files changed

+9
-11
lines changed

py/map.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ STATIC void mp_map_rehash(mp_map_t *map) {
9191
m_del(mp_map_elem_t, old_table, old_alloc);
9292
}
9393

94+
// MP_MAP_LOOKUP behaviour:
95+
// - returns NULL if not found, else the slot it was found in with key,value non-null
96+
// MP_MAP_LOOKUP_ADD_IF_NOT_FOUND behaviour:
97+
// - returns slot, with key non-null and value=MP_OBJ_NULL if it was added
98+
// MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour:
99+
// - returns NULL if not found, else the slot if was found in with key null and value non-null
94100
mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
95101
// if the map is a fixed array then we must do a brute force linear search
96102
if (map->table_is_fixed_array) {
@@ -135,7 +141,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
135141
}
136142
return slot;
137143
} else {
138-
return MP_OBJ_NULL;
144+
return NULL;
139145
}
140146
} else if (slot->key == MP_OBJ_SENTINEL) {
141147
// found deleted slot, remember for later
@@ -146,10 +152,6 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
146152
// found index
147153
// Note: CPython does not replace the index; try x={True:'true'};x[1]='one';x
148154
if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
149-
// this leaks this memory (but see dict_get_helper)
150-
mp_map_elem_t *retval = m_new(mp_map_elem_t, 1);
151-
retval->key = slot->key;
152-
retval->value = slot->value;
153155
// delete element in this slot
154156
map->used--;
155157
if (map->table[(pos + 1) % map->alloc].key == MP_OBJ_NULL) {
@@ -158,7 +160,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
158160
} else {
159161
slot->key = MP_OBJ_SENTINEL;
160162
}
161-
return retval;
163+
// keep slot->value so that caller can access it if needed
162164
}
163165
return slot;
164166
}
@@ -185,7 +187,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
185187
start_pos = pos = hash % map->alloc;
186188
}
187189
} else {
188-
return MP_OBJ_NULL;
190+
return NULL;
189191
}
190192
}
191193
}

py/objdict.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,6 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp
208208
}
209209
} else {
210210
value = elem->value;
211-
if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
212-
// catch the leak (from mp_map_lookup)
213-
m_free(elem, sizeof(mp_map_elem_t));
214-
}
215211
}
216212
if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
217213
elem->value = value;

0 commit comments

Comments
 (0)