commit 07825c97b36a3820727ddd3a73067dd810830f10
parent bbadb5af33b03192d6ecd5e47d344dabedadbbe7
Author: quantumish <freifeld.david@gmail.com>
Date: Wed, 12 Apr 2023 22:21:31 -0700
Experiment with variable-sized hashmap keys
Diffstat:
4 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/http.c b/http.c
@@ -54,9 +54,7 @@ response_t serve_file(request_t req) {
bool ok = true;
char* mtype = (char*)ext_to_mtype(ext);
char* hdr;
- char check[MAX_HEADER_NAME] = {0};
- strcpy(check, "Accept");
- if ((hdr = hashmap_get(&req.headers, check))) {
+ if ((hdr = hashmap_get(&req.headers, "Accept"))) {
log_debug("Handling Accept header");
ok = false;
shitvec_t mtypes = hdr_parse_accept(hdr);
diff --git a/http/request.c b/http/request.c
@@ -62,6 +62,7 @@ int req_parse(request_t* req) {
req->method = method_enum((char*)method);
req->headers = hashmap_new(MAX_HEADER_NAME, MAX_HEADER_VALUE);
+ req->headers.vark = true;
char* start = memchr(req->buf, '\n', MAX_HEADER_NAME+MAX_HEADER_VALUE)+1;
while (start+MAX_HEADER_NAME+MAX_HEADER_VALUE < req->buf+req->bufsize) {
char name[MAX_HEADER_NAME] = {0};
diff --git a/utils/hashmap.c b/utils/hashmap.c
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
+#include "log.h"
#include "hashmap.h"
#define HASHMAP_INIT_SIZE 16
@@ -34,7 +35,6 @@ bool iszero(void *p, size_t len) {
return iszero;
}
-
// Initialize the hashmap pointed to by h.
hashmap_t hashmap_new(size_t ksize, size_t vsize) {
hashmap_t h;
@@ -44,10 +44,22 @@ hashmap_t hashmap_new(size_t ksize, size_t vsize) {
h.k_sz = ksize;
h.v_sz = vsize;
h.len = HASHMAP_INIT_SIZE;
+ h.vark = false;
h.filled = 0; // Store # of filled keys for load factor calculation
return h;
}
+int hashmap_kcmp(hashmap_t* h, void* a, void* b) {
+ log_debug("%s %s", a, b);
+ if (h->vark) return strcmp(a, b);
+ return memcmp(a, b, h->k_sz);
+}
+
+void* hashmap_kcpy(hashmap_t* h, void* a, void* b) {
+ if (h->vark) return strcpy(a, b);
+ return memcpy(a, b, h->k_sz);
+}
+
void hashmap_resize(hashmap_t* h) {
void* tempk = h->keys;
void* tempv = h->vals;
@@ -76,7 +88,7 @@ int hashmap_set(hashmap_t* h, void* k, void* v) {
// Start at the hashed index, iterate until own key or empty key is found
for (size_t off = index; off < h->len; off+=1) {
// Check if stored key at hashed index is equal to key: if so, replace value
- if (memcmp(h->keys + (off*h->k_sz), k, h->k_sz) == 0) {
+ if (hashmap_kcmp(h, h->keys + (off*h->k_sz), k) == 0) {
memcpy(h->vals + (off*h->v_sz), v, h->v_sz);
return 0x0;
}
@@ -84,7 +96,7 @@ int hashmap_set(hashmap_t* h, void* k, void* v) {
if (iszero(h->keys + (off*h->k_sz), h->k_sz)) {
h->filled++;
memcpy(h->vals + (off*h->v_sz), v, h->v_sz);
- memcpy(h->keys + (off*h->k_sz), k, h->k_sz);
+ hashmap_kcpy(k, h->keys + (off*h->k_sz), k);
return 0x0;
}
if (off == h->len-1 && looped_once == 0) {
@@ -103,7 +115,7 @@ void* hashmap_get(hashmap_t* h, void* k) {
// Start at the hashed index, iterate until wanted key or empty key is found
for (size_t off = index; off < h->len; off+=1) {
// Check if entry has correct key
- if (memcmp(h->keys + (off * h->k_sz), k, h->k_sz) == 0) {
+ if (hashmap_kcmp(h, h->keys + (off * h->k_sz), k) == 0) {
return h->vals + (off * h->v_sz);
}
// Empty entry means this key doesn't exist: return not found
@@ -122,7 +134,7 @@ int hashmap_del(hashmap_t* h, void* k) {
size_t index = hash(k, h->k_sz) % h->len;
int looped_once = 0;
for (size_t off = index; off < h->len; off+=1) {
- if (memcmp(h->keys + (off * h->k_sz), k, h->k_sz) == 0) {
+ if (hashmap_kcmp(h, h->keys + (off * h->k_sz), k) == 0) {
memset(h->keys + (off * h->v_sz), 0, h->k_sz);
// No reason to delete value, will just be overwritten next time.
return 0;
diff --git a/utils/hashmap.h b/utils/hashmap.h
@@ -2,6 +2,7 @@
#define HASHMAP_H
#include <stddef.h>
+#include <stdbool.h>
typedef struct hashmap_t {
void* keys;
@@ -10,6 +11,7 @@ typedef struct hashmap_t {
size_t v_sz;
size_t len;
size_t filled;
+ bool vark;
} hashmap_t;
// Generates a new hashmap_t.