summaryrefslogtreecommitdiff
path: root/src/hash.h
blob: f13c63d66dd49951d03e00d82e60863763839ea3 (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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once

#include <mimalloc.h>

#include <cstring>

#include "hashmap.h"
#include "utils.h"

#define WAYC_HASHMAP_SEED 0
#define WAYC_HASHMAP_CAP 16

template <typename K, typename V>
struct hashentry_s {
  K key;
  V value;
};

template <typename K, typename V>
inline u64 wayc_hashentry_hash(const void* item, uint64_t seed0,
                               uint64_t seed1) {
  wayc_notnull(item);

  const hashentry_s<K, V>* entry = (const hashentry_s<K, V>*)item;
  return hashmap_murmur(&entry->key, sizeof(K), seed0, seed1);
}

template <typename K, typename V>
inline i32 wayc_hashentry_compare(const void* a, const void* b, void* udata) {
  (void)udata;

  wayc_notnull(a);
  wayc_notnull(b);

  const hashentry_s<K, V>* entry_a = (const hashentry_s<K, V>*)a;
  const hashentry_s<K, V>* entry_b = (const hashentry_s<K, V>*)b;
  return memcmp(&entry_a->key, &entry_b->key, sizeof(K));
}

template <typename K, typename V>
struct hashmap_s {
  struct hashmap* inner;
};

template <typename K, typename V>
inline void wayc_hashmap_init(hashmap_s<K, V>* map) {
  wayc_notnull(map);
  memset(map, 0, sizeof(*map));

  struct hashmap* inner;
  inner = hashmap_new_with_allocator(
      mi_malloc, mi_realloc, mi_free, sizeof(hashentry_s<K, V>),
      WAYC_HASHMAP_CAP, WAYC_HASHMAP_SEED, WAYC_HASHMAP_SEED,
      wayc_hashentry_hash<K, V>, wayc_hashentry_compare<K, V>, nullptr,
      nullptr);

  wayc_notnull(inner);

  map->inner = inner;
}

template <typename K, typename V>
inline void wayc_hashmap_deinit(hashmap_s<K, V>* map) {
  wayc_notnull(map);
  hashmap_free(map->inner);
}

template <typename K, typename V>
inline V* wayc_hashmap_insert(hashmap_s<K, V>* map, const K* key,
                              const V* value) {
  wayc_notnull(map);
  wayc_notnull(key);
  wayc_notnull(value);

  hashentry_s<K, V> entry{};
  entry.key = *key;
  entry.value = *value;
  hashentry_s<K, V>* stored =
      (hashentry_s<K, V>*)hashmap_set(map->inner, &entry);
  return &stored->value;
}

template <typename K, typename V>
inline V* wayc_hashmap_get(hashmap_s<K, V>* map, const K* key) {
  wayc_notnull(map);
  wayc_notnull(key);

  hashentry_s<K, V> entry{};
  entry.key = *key;
  auto* stored = (hashentry_s<K, V>*)hashmap_get(map->inner, &entry);
  if (!stored) return nullptr;

  return &stored->value;
}

template <typename K, typename V>
inline void wayc_hashmap_remove(hashmap_s<K, V>* map, const K* key) {
  wayc_notnull(map);
  wayc_notnull(key);

  hashentry_s<K, V> entry{};
  entry.key = *key;
  hashmap_delete(map->inner, &entry);
}

template <typename K, typename V>
inline usize wayc_hashmap_count(hashmap_s<K, V>* map) {
  wayc_notnull(map);
  return hashmap_count(map->inner);
}