G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2021-10-30 05:03:42
Commit32a469567dece618c708260d4165727c7d13b5b5
Parentf9a604aa2fc773b05be329c7e68d758d53965d48

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