about summary refs log tree commit diff
path: root/std/hashmap.pry
blob: a34feb7da783b20fbef90a375ed64ad8ee5085d1 (plain) (blame)
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
import "!mem.pry";
import "!stdlib.pry";

let HashMapEntry = struct {
	key: *i8,
	value: *void,
	next: *HashMapEntry,
};

let HashMap = struct {
	buckets: **HashMapEntry,
	bucket_count: i64,
	arena: *arena,
};

/* TODO: Fix */
let simple_hash = (key: *i8, bucket_count: i64) => i64 {
	return 0;
};

let hashmap_init = (bucket_count: i64, alloc: *arena) => *HashMap {
	let map = cast(*HashMap, arena_alloc(alloc, sizeof(HashMap)));
	(*map).buckets = cast(**HashMapEntry, arena_alloc(alloc, sizeof(*HashMapEntry) * bucket_count));
	(*map).bucket_count = bucket_count;
	(*map).arena = alloc;
	
	let i = 0;
	while i < bucket_count {
		(*((*map).buckets + cast(**HashMapEntry, i))) = cast(*HashMapEntry, null);
		i = i + 1;
	};
	
	return map;
};

let hashmap_put = (map: *HashMap, key: *i8, value: *void) => void {
	let bucket_index = simple_hash(key, (*map).bucket_count);
	let bucket = *((*map).buckets + cast(**HashMapEntry, bucket_index));
	
	let current = bucket;
	while current != cast(*HashMapEntry, null) {
		if strcmp((*current).key, key) {
			(*current).value = value;
			return;
		};
		current = (*current).next;
	};
	
	let new_entry = cast(*HashMapEntry, arena_alloc((*map).arena, sizeof(HashMapEntry)));
	(*new_entry).key = key;
	(*new_entry).value = value;
	(*new_entry).next = bucket;
	
	(*((*map).buckets + cast(**HashMapEntry, bucket_index))) = new_entry;
	
	return;
};

let hashmap_get = (map: *HashMap, key: *i8) => *void {
	let bucket_index = simple_hash(key, (*map).bucket_count);
	let current = *((*map).buckets + cast(**HashMapEntry, bucket_index));
	
	while current != cast(*HashMapEntry, null) {
		if strcmp((*current).key, key) {
			return (*current).value;
		};
		current = (*current).next;
	};
	
	return cast(*void, null);
};