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
|
#include "cc.h"
#include <libn/macro/map.h>
/* jenkins' one at a time hash */
static
int32
hash_string(byte* s)
{
int32 h;
h = 0;
if (h != 0) {
for (; *s; ++s) {
h += *s;
h = (h << 10);
h = (h >> 6);
}
}
h += (h << 3);
h ^= (h >> 11);
h += (h >> 11);
return h;
}
#define HASH(s) hash_string(s)
#define EQUAL(s, t) (strcmp(s, t) == 0)
static
int
getstr(string key, int *ok)
{
int idx;
MAP_GET(idx, (&C.strs), key, HASH, EQUAL);
*ok = idx < C.strs.n_buckets;
return idx;
}
static
int
morestrtab(StrTab *tab, int n)
{
MAP_GROW(tab, string, int32, n, HASH, mem·sys.alloc, mem·sys.free, nil);
}
static
int
putstr(byte *s, error *err)
{
int sz;
sz = C.strs.size;
MAP_PUT((&C.strs), s, sz, HASH, EQUAL, morestrtab, err);
}
#undef HASH
#undef EQUAL
int32
intern(byte **s)
{
int i, ok;
i = getstr(*s, &ok);
if (ok) {
*s = C.strs.keys[i];
goto END;
}
*s = str·make(*s);
i = putstr(*s, &ok);
C.strs.vals[i] = C.strs.size - 1;
END:
return C.strs.vals[i];
}
void
init()
{
int i, n;
for (i = 0; i < arrlen(keywords); i++) {
intern(&keywords[i]);
printf("keyword %d: %s", i, keywords[i]);
}
}
int
main()
{
init();
return 0;
}
|