commit ec8e5a7343354704d5cab7d141db3cebd548c41a
parent aeb75c79da07bbb6432c5d701acd094f39cb4877
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 20 Mar 2023 02:47:34 +0100
Update hashmap implementation
Diffstat:
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