-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfixed_map.h
More file actions
101 lines (81 loc) · 2.38 KB
/
Copy pathfixed_map.h
File metadata and controls
101 lines (81 loc) · 2.38 KB
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
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include "../allocators/scratch.h"
#include "hashes.h"
typedef struct {
uint64_t key;
uint64_t val;
} FixedMapEntry;
typedef struct {
FixedMapEntry *entries;
uint64_t entries_size;
uint64_t entries_capacity;
int64_t *hashes;
uint64_t hashes_size;
ScratchAlloc *scr;
} FixedMap;
FixedMap fixed_map_init(ScratchAlloc *scr, int elem_count) {
FixedMap m;
int start_count = elem_count;
if (start_count == 0) {
start_count = 8;
}
m.hashes = (int64_t *)scratch_alloc(scr, sizeof(int64_t) * start_count);
m.hashes_size = start_count;
m.entries = (FixedMapEntry *)scratch_alloc(scr, sizeof(FixedMapEntry) * start_count);
m.entries_size = 0;
m.entries_capacity = start_count;
// Set the whole hashmap to empty. -1 means the slot hasn't been filled yet
for (int i = 0; i < m.hashes_size; i++) {
m.hashes[i] = -1;
}
return m;
}
bool fixed_map_insert(FixedMap *m, uint64_t key, uint64_t val) {
FixedMapEntry new_entry = {key, val};
uint64_t hash_val = fibhash(key) % m->hashes_size;
for (uint64_t i = 0; i < m->hashes_size; i++) {
uint64_t cur_hash_idx = (hash_val + i) % m->hashes_size;
int64_t cur_hash = m->hashes[cur_hash_idx];
// Did we find an empty slot?
if (cur_hash == -1) {
m->hashes[cur_hash_idx] = m->entries_size;
m->entries[m->entries_size] = new_entry;
m->entries_size++;
return true;
// Is this key already in the map? If so, replace the entry with our new entry
} else if (m->entries[cur_hash].key == key) {
m->entries[cur_hash] = new_entry;
return true;
}
}
// Our hashmap is completely full?
return false;
}
bool fixed_map_get(FixedMap *m, uint64_t key, uint64_t *result) {
uint64_t hash_val = fibhash(key) % m->hashes_size;
for (uint64_t i = 0; i < m->hashes_size; i++) {
uint64_t cur_hash_idx = (hash_val + i) % m->hashes_size;
int64_t cur_hash = m->hashes[cur_hash_idx];
// There's nothing in our hashmap with our key?
if (cur_hash == -1) {
*result = 0;
return false;
// Did we find it? Check to make sure the entry we found has a matching key
} else if (m->entries[cur_hash].key == key) {
*result = m->entries[cur_hash].val;
return true;
}
}
// The hashmap is completely full?
*result = 0;
return false;
}
void fixed_map_clear(FixedMap *m) {
for (int i = 0; i < m->hashes_size; i++) {
m->hashes[i] = -1;
}
m->entries_size = 0;
}