Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
hashmap.ha — paste.sr.ht
[go: Go Back, main page]

# hashmap.ha -rw-r--r-- 1.9 KiB View raw
                                                                                
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
// A simple hash table mapping string keys to string values.
use fmt;
use hash::fnv;

def BUCKETS: size = 64;

type hashmap = [BUCKETS][](str, str);

// Retrives the value associated with the given key in a [[hashmap]], or void if
// no such key exists.
fn get(map: *hashmap, key: str) (str | void) = {
	const hash = fnv::string(key);
	const bucket = &map[hash % len(map)];
	for (let (k, v) .. bucket) {
		if (k == key) {
			return v;
		};
	};
};

// Sets the value associated with the given key in a [[hashmap]]. Both the key
// and value are borrowed from the caller.
fn set(map: *hashmap, key: str, val: str) void = {
	const hash = fnv::string(key);
	let bucket = &map[hash % len(map)];
	for (let i = 0z; i < len(bucket); i += 1) {
		if (bucket[i].0 == key) {
			bucket[i] = (key, val);
			return;
		};
	};
	append(bucket, (key, val));
};

// Unsets a value in a [[hashmap]] associated with a given key, returning the
// value that was previously stored for that key (or void).
fn unset(map: *hashmap, key: str) (str | void) = {
	const hash = fnv::string(key);
	let bucket = &map[hash % len(map)];
	for (let i = 0z; i < len(bucket); i += 1) {
		const (k, v) = bucket[i];
		if (k == key) {
			delete(bucket[i]);
			return v;
		};
	};
};

// Frees resources associated with a [[hashmap]].
fn finish(map: *hashmap) void = {
	for (let bucket .. map) {
		free(bucket);
	};
};

// Demonstrate usage of the hash map
export fn main() void = {
	let map: hashmap = [[]...];
	defer finish(&map);

	set(&map, "hello", "world");
	set(&map, "foo", "bar");

	assert(get(&map, "hello") as str == "world");
	assert(get(&map, "foo") as str == "bar");
	assert(get(&map, "hi there") is void);

	assert(unset(&map, "hello") as str == "world");
	assert(get(&map, "hello") is void);

	// Enumerate keys/values
	for (let bucket .. map) {
		for (let (key, val) .. bucket) {
			fmt::printfln("{}: {}", key, val)!;
		};
	};
};