aoc-2019-c

git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

commit ec8e5a7343354704d5cab7d141db3cebd548c41a
parent aeb75c79da07bbb6432c5d701acd094f39cb4877
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 20 Mar 2023 02:47:34 +0100

Update hashmap implementation

Diffstat:
M06/main.c | 38+++++++++++++++++++++-----------------
M10/main.c | 19++++++++++++-------
Mcommon/iccmp.c | 29+++++++++++++++++++++--------
3 files changed, 54 insertions(+), 32 deletions(-)

diff --git a/06/main.c b/06/main.c @@ -4,6 +4,7 @@ #include "allocator.h" #include "util.h" +#include <assert.h> #include <errno.h> #include <stdio.h> #include <string.h> @@ -19,7 +20,7 @@ struct planet { struct hashmap planets; struct planet * -get_planet(const char *name) +planets_get(const char *name) { struct hashmap_link *link; int status; @@ -29,26 +30,27 @@ get_planet(const char *name) } struct planet * -add_planet(const char *name) +planets_add(const char *name) { struct planet *p; + int rc; p = malloc(sizeof(struct planet)); - if (!p) die("main: add_planet: malloc"); + if (!p) die("main: planets_add: malloc"); p->name = aprintf("%s", name); p->parent = NULL; dvec_init(&p->children, sizeof(struct planet *), 3, &stdlib_heap_allocator); - hashmap_set(&planets, aprintf("%s", name), strlen(name), - p, sizeof(struct planet)); + rc = hashmap_add(&planets, aprintf("%s", name), strlen(name), p); + assert(!rc); return p; } void -init_planets() +planets_init() { struct planet *parent, *child, **slot; const char *pos, *end; @@ -65,11 +67,11 @@ init_planets() if (!sep) die("main: bad format"); *sep = '\0'; - parent = get_planet(buf); - if (!parent) parent = add_planet(buf); + parent = planets_get(buf); + if (!parent) parent = planets_add(buf); - child = get_planet(sep + 1); - if (!child) child = add_planet(sep + 1); + child = planets_get(sep + 1); + if (!child) child = planets_add(sep + 1); slot = dvec_add_slot(&parent->children, &rc); if (rc) die("main: dvec_add_slot"); @@ -81,15 +83,17 @@ init_planets() } void -deinit_planets() +planets_deinit() { struct hashmap_iter iter; struct planet *p; for (HASHMAP_ITER(&planets, &iter)) { + free(iter.link->key); p = iter.link->value; dvec_deinit(&p->children); free(p->name); + free(p); } hashmap_deinit(&planets); @@ -102,7 +106,7 @@ part1(void) struct planet *p; int orbits; - init_planets(); + planets_init(); orbits = 0; for (HASHMAP_ITER(&planets, &iter)) { @@ -116,7 +120,7 @@ part1(void) aoc.answer = aprintf("%i", orbits); aoc.solution = "119831"; - deinit_planets(); + planets_deinit(); } void @@ -125,11 +129,11 @@ part2(void) struct planet *p1, *p2, *san, *you; int i, s1, s2; - init_planets(); + planets_init(); - san = get_planet("SAN"); + san = planets_get("SAN"); if (!san) die("main: missing planet SAN"); - you = get_planet("YOU"); + you = planets_get("YOU"); if (!you) die("main: missing planet YOU"); for (s1 = 0, p1 = you; p1; p1 = p1->parent, s1++) { @@ -143,5 +147,5 @@ exit: aoc.answer = aprintf("%i", s1 + s2 - 2); aoc.solution = "322"; - deinit_planets(); + planets_deinit(); } diff --git a/10/main.c b/10/main.c @@ -78,7 +78,7 @@ asteroids_init(void) } void -asteroids_free(void) +asteroids_deinit(void) { struct asteroid *iter, *next; @@ -134,12 +134,10 @@ get_vis(struct hashmap *hm, struct asteroid *a1) odir = (struct dir) { tmp->x - a1->x, tmp->y - a1->y }; dir = (struct dir) { a2->x - a1->x, a2->y - a1->y }; if (ABS(odir.dx) + ABS(odir.dy) > ABS(dir.dx) + ABS(dir.dy)) - link->value = memdup(a2, sizeof(struct asteroid)); + link->value = a2; } else { key = memdup(&dir, sizeof(struct dir)); - value = memdup(a2, sizeof(struct asteroid)); - rc = hashmap_set(hm, NULL, key, sizeof(struct dir), - value, sizeof(struct asteroid)); + rc = hashmap_add(hm, key, sizeof(struct dir), a2); assert(!rc); } } @@ -182,6 +180,8 @@ find_base(struct asteroid **a_out, int *vis_out) cand = a1; } + for (HASHMAP_ITER(&dirmap, &iter)) + free(iter.link->key); hashmap_clear(&dirmap); } @@ -205,7 +205,7 @@ part1(void) aoc.answer = aprintf("%i", vis); aoc.solution = "299"; - asteroids_free(); + asteroids_deinit(); } void @@ -253,6 +253,11 @@ part2(void) aoc.answer = aprintf("%i", list[199]->x * 100 + list[199]->y); aoc.solution = "1419"; - asteroids_free(); + free(list); + + for (HASHMAP_ITER(&dirmap, &iter)) + free(iter.link->key); + + asteroids_deinit(); hashmap_deinit(&dirmap); } diff --git a/common/iccmp.c b/common/iccmp.c @@ -76,6 +76,8 @@ icc_init(struct icc *icc) void icc_deinit(struct icc *icc) { + struct hashmap_iter iter; + mi_deinit(&icc->rip); mi_deinit(&icc->base); mi_deinit(&icc->in); @@ -87,6 +89,14 @@ icc_deinit(struct icc *icc) mi_deinit(&icc->r3); mi_deinit(&icc->r4); mi_deinit(&icc->tmp); + + for (HASHMAP_ITER(&icc->instructions, &iter)) { + mi_deinit(iter.link->key); + free(iter.link->key); + mi_deinit(iter.link->value); + free(iter.link->value); + } + hashmap_deinit(&icc->instructions); } @@ -144,9 +154,8 @@ icc_parse_inst(struct icc *icc, const char *str, size_t len) mi_init(val); mi_setv(val, ABS(v), v >= 0 ? MI_POS : MI_NEG); - rc = hashmap_set(&icc->instructions, NULL, - key, sizeof(struct maxint), - val, sizeof(struct maxint)); + rc = hashmap_add(&icc->instructions, key, + sizeof(struct maxint), val); assert(!rc); rip += 1; @@ -559,8 +568,9 @@ icc_step_inst(struct icc *icc) struct hashmap_link * icc_write_any(struct icc *icc, struct maxint *addr, struct maxint *value) { - struct hashmap_link *link; + struct hashmap_link **link; struct maxint *key, *val; + int rc; key = malloc(sizeof(struct maxint)); assert(key != NULL); @@ -572,11 +582,14 @@ icc_write_any(struct icc *icc, struct maxint *addr, struct maxint *value) mi_init(val); mi_set(val, value); - assert(!hashmap_set(&icc->instructions, &link, - key, sizeof(struct maxint), - val, sizeof(struct maxint))); + link = hashmap_link_pos(&icc->instructions, key, sizeof(struct maxint)); + if (!*link) { + rc = hashmap_link_alloc(&icc->instructions, link, + key, sizeof(struct maxint), val); + assert(!rc); + } - return link; + return *link; } int