diff --git a/src/map.c b/src/map.c index f22c834..eed3488 100644 --- a/src/map.c +++ b/src/map.c @@ -31,6 +31,9 @@ struct map_entry { struct map_item *item; }; +/* Marker for deleted items */ +static struct map_item deleted; + void map_destroy(struct map *map) { free(map->data); @@ -43,7 +46,8 @@ void map_clear(struct map *map, void (*release)(struct map_item *)) for (i = 0; i < map->size; ++i){ if (!map->data[i].item) continue; - (* release)(map->data[i].item); + if (map->data[i].item != &deleted) + (* release)(map->data[i].item); map->data[i].item = NULL; } map->count = 0; @@ -69,7 +73,7 @@ static int map_hash(struct map *map, unsigned int key) for (i = 0; i < map->size; ++i) { e = &map->data[idx]; - if (!e->item) { + if (!e->item || e->item == &deleted) { ++map->count; return idx; } @@ -94,8 +98,12 @@ int map_reput(struct map *map, unsigned int key, struct map_item *value, return rc; } - if (old) - *old = map->data[rc].item; + if (old) { + if (map->data[rc].item == &deleted) + *old = NULL; + else + *old = map->data[rc].item; + } map->data[rc].item = value; if (value) map->data[rc].item->key = key; @@ -126,7 +134,7 @@ static int map_rehash(struct map *map) map->count = 0; for (i = 0; i < o_size; ++i){ - if (!oldt[i].item) + if (!oldt[i].item || oldt[i].item == &deleted) continue; rc = map_put(map, oldt[i].item->key, oldt[i].item); if (rc < 0) @@ -150,11 +158,14 @@ static struct map_entry *map_find(const struct map *map, unsigned int key) for (i = 0; i < map->size; ++i) { e = &map->data[idx]; + idx = (idx + 1) % map->size; + if (!e->item) break; + if (e->item == &deleted) + continue; if (e->item->key == key) return e; - idx = (idx + 1) % map->size; } return NULL; } @@ -180,7 +191,7 @@ int map_remove(struct map *map, unsigned int key) e = map_find(map, key); if (e) { - e->item = NULL; + e->item = &deleted; --map->count; } return !e; @@ -196,7 +207,7 @@ static struct map_entry *map_iter_from(const struct map *map, unsigned int start unsigned int i = start; for (; i < map->size; ++i) { - if (map->data[i].item) + if (map->data[i].item && map->data[i].item != &deleted) return &map->data[i]; } return NULL;