Author | Jakob Wakeling <[email protected]> |
Date | 2021-10-30 05:03:42 |
Commit | 32a469567dece618c708260d4165727c7d13b5b5 |
Parent | f9a604aa2fc773b05be329c7e68d758d53965d48 |
map: Simplify the map implementation
Diffstat
M | src/map.c | | | 68 | ++++++++++++++++++++++---------------------------------------------- |
M | src/map.h | | | 11 | ++++++----- |
2 files changed, 28 insertions, 51 deletions
diff --git a/src/map.c b/src/map.c index 4c059a8..5c6b86c 100644 --- a/src/map.c +++ b/src/map.c @@ -8,17 +8,12 @@ #include "map.h" #include "util/util.h" +#include "cll/error.h" #include "cll/fnv.h" #include <stdlib.h> #include <string.h> -/* Initialise a new map entry. */ -static inline ent *ent_init(u8 *k, sym v) { - ent *e = calloc(1, sizeof (*e)); if (!e) { return NULL; } - e->k = (u8 *)strdup((char *)k); e->v = v; return e; -} - /* Grow a map. */ static inline void map_grow(map *m) { /* TODO */ @@ -30,58 +25,39 @@ static inline void map_hash(map *m) { } /* Initialise a map. */ -extern void map_init(map *m) { +void map_init(map *m) { m->al = 0; m->ac = 1024; m->a = calloc(m->ac, sizeof (ent *)); - /* TODO check memory allocation */ } /* Free a map. */ -extern void map_free(map *m) { - for (register ent *e = m->c, *f; e; e = f) { - f = e->c; free(e->k); free(e); - } free(m->a); free(m); +void map_free(map *m) { + /* TODO */ } -/* Get the element associated with a key. */ -extern sym *map_get(map *m, u8 *k) { - register ent *e = m->a[fnv1a64((u8 *)k, strlen((char *)k)) % m->ac]; +/* Insert an element into a map. */ +void map_insert(map *m, u8 *k, sym v) { + if ((f64)m->al / m->ac >= 0.75) { /* TODO */ warn("map_insert growth"); } - /* Check if the key is present in the bucket */ - for (; e; e = e->n) { - if (!strcmp((char *)k, (char *)e->k)) { return &e->v; } - } + u64 i = fnv1a64(k, strlen((char *)k)) % m->ac; - return NULL; + register ent *e = calloc(1, sizeof (*e)); /* TODO check memory allocation */ + e->k = (u8 *)strdup((char *)k); e->v = v; e->n = m->a[i]; m->a[i] = e; } -/* Set the element associated with a key. */ -extern void map_set(map *m, u8 *k, sym v) { - if ((f64)m->al / m->ac >= 0.75) { map_grow(m); } - - u64 i = fnv1a64((u8 *)k, strlen((char *)k)) % m->ac; - register ent *e = m->a[i]; +/* Lookup an element in a map. */ +sym *map_lookup(map *m, u8 *k) { + u64 i = fnv1a64(k, strlen((char *)k)) % m->ac; - /* Check if the bucket is completely empty */ - if (!e) { - m->a[i] = ent_init(k, v); /* TODO check memory allocation */ - ++m->al; m->a[i]->c = m->c; m->c = m->a[i]; return; - } - - /* Check if the key matches the first entry in the bucket */ - if (!strcmp((char *)k, (char *)e->k)) { e->v = v; return; } - - /* Check if the key is already present in the rest of the bucket */ - for (; e->n; e = e->n) { - if (!strcmp((char *)k, (char *)e->n->k)) { e->n->v = v; return; } + for (register ent *e = m->a[i]; e; e = e->n) { + if (!strcmp((char *)k, (char *)e->k)) { return &e->v; } } - /* Add a new entry at the end of the bucket */ - e->n = ent_init(k, v); /* TODO check memory allocation */ - ++m->al; e->n->c = m->c; m->c = e->n; return; + return NULL; } -/* Delete the element associated with a key. */ -extern void map_del(map *m, u8 *k) { - /* TODO */ +/* Pop an element from a map. */ +void map_pop(map *m, u8 *k) { + u64 i = fnv1a64(k, strlen((char *)k)) % m->ac; + m->a[i] = m->a[i]->n; /* TODO deallocate memory */ } diff --git a/src/map.h b/src/map.h index 22076c5..3233003 100644 --- a/src/map.h +++ b/src/map.h @@ -11,18 +11,18 @@ #include "util/util.h" #include "type.h" -typedef enum { SK_VOID, } ent_k; /* Entry Kind */ -typedef enum { SF_VOID = BIT(0), } ent_f; /* Entry Flag */ +typedef enum { SK_VOID, } sym_k; /* Symbol Kind */ +typedef enum { SF_VOID = BIT(0), } sym_f; /* Symbol Flag */ -typedef struct sym { ent_k k; ent_f f; type t; } sym; +typedef struct sym { sym_k k; sym_f f; type t; } sym; typedef struct ent { u8 *k; sym v; struct ent *n, *c; } ent; typedef struct { ent **a, *c; usize al, ac; } map; extern void map_init(map *m); extern void map_free(map *m); -extern sym *map_get(map *m, u8 *k); -extern void map_put(map *m, u8 *k, sym s); -extern void map_del(map *m, u8 *k); +extern void map_insert(map *m, u8 *k, sym s); +extern sym *map_lookup(map *m, u8 *k); +extern void map_pop(map *m, u8 *k); #endif // G_MAP_H_ISL5XLWM