shithub: sl

Download patch

ref: 83185ad9f68ed39250938c91877deedb16cb67d6
parent: fcdc5b4a8db42f064830bb5fa25f6f020fa121c6
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Thu Jan 2 00:32:59 EST 2025

htable.inc: take macros from outside instead of defining one

This makes debugging possible since the file/line mapping is
now pointing at htable.inc, rather than always at a single line
with a macro call.

--- a/equalhash.c
+++ b/equalhash.c
@@ -1,8 +1,9 @@
 #include "flisp.h"
 #include "equalhash.h"
 #include "equal.h"
-#include "htable.inc"
 
-#define _equal_lispvalue_(x, y) equal_lispvalue((value_t)(x), (value_t)(y))
+#define HTNAME(suffix) equalhash##suffix
+#define HFUNC hash_lispvalue
+#define EQFUNC(x, y) equal_lispvalue((value_t)(x), (value_t)(y))
 
-HTIMPL(equalhash, hash_lispvalue, _equal_lispvalue_)
+#include "htable.inc"
--- a/htable.inc
+++ b/htable.inc
@@ -1,8 +1,6 @@
 //-*- mode:c -*-
 
-/*
-  include this file and call HTIMPL to generate an implementation
-*/
+// define HTNAME, HFUNC and EQFUNC, then include this header
 
 #define hash_size(h) ((h)->size/2)
 
@@ -9,139 +7,138 @@
 // compute empirical max-probe for a given size
 #define max_probe(size) ((size) <= (HT_N_INLINE*2) ? (HT_N_INLINE/2) : (size)>>3)
 
-#define HTIMPL(HTNAME, HFUNC, EQFUNC) \
-static void ** \
-HTNAME##_lookup_bp(htable_t *h, void *key) \
-{ \
-	value_t hv; \
-	size_t i, orig, index, iter; \
-	size_t newsz, sz = hash_size(h); \
-	size_t maxprobe = max_probe(sz); \
-	void **tab = h->table; \
-	void **ol; \
- \
-	hv = HFUNC((uintptr_t)key); \
-retry_bp: \
-	iter = 0; \
-	index = (hv & (sz-1)) * 2; \
-	sz *= 2; \
-	orig = index; \
- \
-	do{ \
-		if(tab[index+1] == HT_NOTFOUND){ \
-			tab[index] = key; \
-			return &tab[index+1]; \
-		} \
-		if(EQFUNC(key, tab[index])) \
-			return &tab[index+1]; \
-		index = (index+2) & (sz-1); \
-		iter++; \
-		if(iter > maxprobe) \
-			break; \
-	}while(index != orig); \
- \
-	/* table full */ \
-	/* quadruple size, rehash, retry the insert */ \
-	/* it's important to grow the table really fast; otherwise we waste */ \
-	/* lots of time rehashing all the keys over and over. */ \
-	sz = h->size; \
-	ol = h->table; \
-	if(sz >= (1<<19) || (sz <= (1<<8))) \
-		newsz = sz<<1; \
-	else if(sz <= HT_N_INLINE) \
-		newsz = HT_N_INLINE; \
-	else \
-		newsz = sz<<2; \
-	tab = (void**)MEM_ALLOC(newsz*sizeof(void*)); \
-	if(tab == nil) \
-		return nil; \
-	for(i = 0; i < newsz; i++) \
-		tab[i] = HT_NOTFOUND; \
-	h->table = tab; \
-	h->size = newsz; \
-	for(i = 0; i < sz; i += 2) { \
-		if(ol[i+1] != HT_NOTFOUND) \
-			(*HTNAME##_lookup_bp(h, ol[i])) = ol[i+1]; \
-	} \
-	if(ol != &h->_space[0]) \
-		MEM_FREE(ol); \
-	sz = hash_size(h); \
-	maxprobe = max_probe(sz); \
-	tab = h->table; \
-	goto retry_bp; \
-}                                                                       \
- \
-void \
-HTNAME##_put(htable_t *h, void *key, void *val) \
-{ \
-    void **bp = HTNAME##_lookup_bp(h, key); \
-    *bp = val; \
-} \
- \
-void ** \
-HTNAME##_bp(htable_t *h, void *key) \
-{ \
-    return HTNAME##_lookup_bp(h, key); \
-} \
- \
-/* returns bp if key is in hash, otherwise nil */ \
-/* if return is non-nil and *bp == HT_NOTFOUND then key was deleted */ \
-static void ** \
-HTNAME##_peek_bp(htable_t *h, void *key) \
-{ \
-    size_t sz = hash_size(h); \
-    size_t maxprobe = max_probe(sz); \
-    void **tab = h->table; \
-    size_t index = (HFUNC((uintptr_t)key) & (sz-1)) * 2; \
-    sz *= 2; \
-    size_t orig = index; \
-    size_t iter = 0; \
- \
-    do { \
-        if(tab[index] == HT_NOTFOUND) \
-            return nil; \
-        if(EQFUNC(key, tab[index])) \
-            return &tab[index+1]; \
- \
-        index = (index+2) & (sz-1); \
-        iter++; \
-        if(iter > maxprobe) \
-            break; \
-    }while(index != orig); \
- \
-    return nil; \
-} \
- \
-void *\
-HTNAME##_get(htable_t *h, void *key) \
-{ \
-    void **bp = HTNAME##_peek_bp(h, key); \
-    if(bp == nil) \
-        return HT_NOTFOUND; \
-    return *bp; \
-} \
- \
-int \
-HTNAME##_has(htable_t *h, void *key) \
-{ \
-    return HTNAME##_get(h, key) != HT_NOTFOUND; \
-} \
- \
-int \
-HTNAME##_remove(htable_t *h, void *key) \
-{ \
-    void **bp = HTNAME##_peek_bp(h, key); \
-    if(bp != nil){ \
-        *bp = HT_NOTFOUND; \
-        return 1; \
-    } \
-    return 0; \
-} \
- \
-void \
-HTNAME##_adjoin(htable_t *h, void *key, void *val) \
-{ \
-    void **bp = HTNAME##_lookup_bp(h, key); \
-    if(*bp == HT_NOTFOUND) \
-        *bp = val; \
+static void **
+HTNAME(_lookup_bp)(htable_t *h, void *key)
+{
+	value_t hv;
+	size_t i, orig, index, iter;
+	size_t newsz, sz = hash_size(h);
+	size_t maxprobe = max_probe(sz);
+	void **tab = h->table;
+	void **ol;
+
+	hv = HFUNC((uintptr_t)key);
+retry_bp:
+	iter = 0;
+	index = (hv & (sz-1)) * 2;
+	sz *= 2;
+	orig = index;
+
+	do{
+		if(tab[index+1] == HT_NOTFOUND){
+			tab[index] = key;
+			return &tab[index+1];
+		}
+		if(EQFUNC(key, tab[index]))
+			return &tab[index+1];
+		index = (index+2) & (sz-1);
+		iter++;
+		if(iter > maxprobe)
+			break;
+	}while(index != orig);
+
+	/* table full */
+	/* quadruple size, rehash, retry the insert */
+	/* it's important to grow the table really fast; otherwise we waste */
+	/* lots of time rehashing all the keys over and over. */
+	sz = h->size;
+	ol = h->table;
+	if(sz >= (1<<19) || (sz <= (1<<8)))
+		newsz = sz<<1;
+	else if(sz <= HT_N_INLINE)
+		newsz = HT_N_INLINE;
+	else
+		newsz = sz<<2;
+	tab = (void**)MEM_ALLOC(newsz*sizeof(void*));
+	if(tab == nil)
+		return nil;
+	for(i = 0; i < newsz; i++)
+		tab[i] = HT_NOTFOUND;
+	h->table = tab;
+	h->size = newsz;
+	for(i = 0; i < sz; i += 2) {
+		if(ol[i+1] != HT_NOTFOUND)
+			(*HTNAME(_lookup_bp)(h, ol[i])) = ol[i+1];
+	}
+	if(ol != &h->_space[0])
+		MEM_FREE(ol);
+	sz = hash_size(h);
+	maxprobe = max_probe(sz);
+	tab = h->table;
+	goto retry_bp;
+}
+
+void
+HTNAME(_put)(htable_t *h, void *key, void *val)
+{
+    void **bp = HTNAME(_lookup_bp)(h, key);
+    *bp = val;
+}
+
+void **
+HTNAME(_bp)(htable_t *h, void *key)
+{
+    return HTNAME(_lookup_bp)(h, key);
+}
+
+/* returns bp if key is in hash, otherwise nil */
+/* if return is non-nil and *bp == HT_NOTFOUND then key was deleted */
+static void **
+HTNAME(_peek_bp)(htable_t *h, void *key)
+{
+    size_t sz = hash_size(h);
+    size_t maxprobe = max_probe(sz);
+    void **tab = h->table;
+    size_t index = (HFUNC((uintptr_t)key) & (sz-1)) * 2;
+    sz *= 2;
+    size_t orig = index;
+    size_t iter = 0;
+
+    do {
+        if(tab[index] == HT_NOTFOUND)
+            return nil;
+        if(EQFUNC(key, tab[index]))
+            return &tab[index+1];
+
+        index = (index+2) & (sz-1);
+        iter++;
+        if(iter > maxprobe)
+            break;
+    }while(index != orig);
+
+    return nil;
+}
+
+void *
+HTNAME(_get)(htable_t *h, void *key)
+{
+    void **bp = HTNAME(_peek_bp)(h, key);
+    if(bp == nil)
+        return HT_NOTFOUND;
+    return *bp;
+}
+
+int
+HTNAME(_has)(htable_t *h, void *key)
+{
+    return HTNAME(_get)(h, key) != HT_NOTFOUND;
+}
+
+int
+HTNAME(_remove)(htable_t *h, void *key)
+{
+    void **bp = HTNAME(_peek_bp)(h, key);
+    if(bp != nil){
+        *bp = HT_NOTFOUND;
+        return 1;
+    }
+    return 0;
+}
+
+void
+HTNAME(_adjoin)(htable_t *h, void *key, void *val)
+{
+    void **bp = HTNAME(_lookup_bp)(h, key);
+    if(*bp == HT_NOTFOUND)
+        *bp = val;
 }
--- a/ptrhash.c
+++ b/ptrhash.c
@@ -5,8 +5,6 @@
 
 #include "flisp.h"
 
-#define OP_EQ(x, y) ((x) == (y))
-
 #if defined(BITS64)
 static uint64_t
 _pinthash(uint64_t key)
@@ -34,6 +32,8 @@
 }
 #endif
 
-#include "htable.inc"
+#define HTNAME(suffix) ptrhash##suffix
+#define HFUNC _pinthash
+#define EQFUNC(x, y) ((x) == (y))
 
-HTIMPL(ptrhash, _pinthash, OP_EQ)
+#include "htable.inc"