Skip to content

Commit d1cee02

Browse files
committed
py: Clarify API for map/set lookup when removing&adding at once.
Addresses issue adafruit#1160.
1 parent d48035b commit d1cee02

3 files changed

Lines changed: 14 additions & 10 deletions

File tree

py/map.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
150150
// and it won't necessarily benefit subsequent calls because these calls
151151
// most likely won't pass the newly-interned string.
152152
compare_only_ptrs = false;
153-
} else if (!(lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)) {
153+
} else if (lookup_kind != MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
154154
// If we are not adding, then we can return straight away a failed
155155
// lookup because we know that the index will never be found.
156156
return NULL;
@@ -193,7 +193,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
193193
// map is a hash table (not an ordered array), so do a hash lookup
194194

195195
if (map->alloc == 0) {
196-
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
196+
if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
197197
mp_map_rehash(map);
198198
} else {
199199
return NULL;
@@ -208,7 +208,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
208208
mp_map_elem_t *slot = &map->table[pos];
209209
if (slot->key == MP_OBJ_NULL) {
210210
// found NULL slot, so index is not in table
211-
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
211+
if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
212212
map->used += 1;
213213
if (avail_slot == NULL) {
214214
avail_slot = slot;
@@ -230,7 +230,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
230230
} else if (slot->key == index || (!compare_only_ptrs && mp_obj_equal(slot->key, index))) {
231231
// found index
232232
// Note: CPython does not replace the index; try x={True:'true'};x[1]='one';x
233-
if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
233+
if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) {
234234
// delete element in this slot
235235
map->used--;
236236
if (map->table[(pos + 1) % map->alloc].key == MP_OBJ_NULL) {
@@ -249,7 +249,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t
249249

250250
if (pos == start_pos) {
251251
// search got back to starting position, so index is not in table
252-
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
252+
if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
253253
if (avail_slot != NULL) {
254254
// there was an available slot, so use that
255255
map->used++;
@@ -298,6 +298,9 @@ STATIC void mp_set_rehash(mp_set_t *set) {
298298
}
299299

300300
mp_obj_t mp_set_lookup(mp_set_t *set, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) {
301+
// Note: lookup_kind can be MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND which
302+
// is handled by using bitwise operations.
303+
301304
if (set->alloc == 0) {
302305
if (lookup_kind & MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) {
303306
mp_set_rehash(set);

py/obj.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,12 @@ typedef struct _mp_map_t {
159159
mp_map_elem_t *table;
160160
} mp_map_t;
161161

162-
// These can be or'd together
162+
// mp_set_lookup requires these constants to have the values they do
163163
typedef enum _mp_map_lookup_kind_t {
164-
MP_MAP_LOOKUP, // 0
165-
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND, // 1
166-
MP_MAP_LOOKUP_REMOVE_IF_FOUND, // 2
164+
MP_MAP_LOOKUP = 0,
165+
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND = 1,
166+
MP_MAP_LOOKUP_REMOVE_IF_FOUND = 2,
167+
MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND = 3, // only valid for mp_set_lookup
167168
} mp_map_lookup_kind_t;
168169

169170
extern const mp_map_t mp_const_empty_map;

py/objset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ STATIC mp_obj_t set_symmetric_difference_update(mp_obj_t self_in, mp_obj_t other
427427
mp_obj_t iter = mp_getiter(other_in);
428428
mp_obj_t next;
429429
while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
430-
mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_REMOVE_IF_FOUND | MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
430+
mp_set_lookup(&self->set, next, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND_OR_REMOVE_IF_FOUND);
431431
}
432432
return mp_const_none;
433433
}

0 commit comments

Comments
 (0)