aboutsummaryrefslogtreecommitdiff
path: root/src/hashmap.c
blob: c68d110e474aa922bf3d2a0f06b604c5e8e5d6ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <chttp/hashmap.h>

size_t hash_str(const_string str, size_t cap) {
  size_t hash = 0;
  for (int i = 0; i < str.len; i++) {
	hash = (HASHMAP_DEFAULT_R * hash + str.data[i]) % cap;
  }
  return hash;
}

hashmap *hashmap_init(arena *a, size_t cap) {
  hashmap *map = arena_alloc(a, sizeof(hashmap) + sizeof(ptrdiff_t) * cap);
  map->cap = cap;
  return map;
}

size_t hashmap_kstr_insert(arena *a, hashmap* map, const_string key, void* val) {
  size_t hash = hash_str(key, map->cap);
  if (map->data[hash].key.len > 0) {
	map->data[hash].next = arena_alloc(a, sizeof(hashitem));
	map->data[hash].next->key = key;
	map->data[hash].next->val = val;
  } else {
	map->data[hash].key = key;
	map->data[hash].val = val;
  }

  return hash;
}

void *hashmap_kstr_get(hashmap *map, const_string key) {
  size_t hash = hash_str(key, map->cap);
  hashitem *item = &map->data[hash];
  while (item->next != NULL && !cs_eq(item->key, key)) {
	item = item->next;
  }

  if (!cs_eq(item->key, key)) {
	return NULL;
  }

  return item->val;
}