annotate src/ploki/hash.c @ 10131:bbbdb09e6365

<boily> le/rn mate//Mat\xc3\xa9 is a southern hemisphere shamanist beverage that opens your inner self to the Sacred World. Its enlightened users become friendly, wishing \xe2\x80\x9cG\'day, mat\xc3\xa9!\xe2\x80\x9d to one another.
author HackBot
date Sat, 14 Jan 2017 14:02:22 +0000
parents ac0403686959
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4223
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
1 #include "config.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
2 #include "hash.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
3 #include "main.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
4 #include "main_opt.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
5 #include "random.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
6 #include "xmalloc.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
7
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
8 #include <errno.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
9 #include <stddef.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
10 #include <stdio.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
11 #include <assert.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
12
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
13 struct h_entry {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
14 size_t hash;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
15 void *key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
16 void *value;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
17 };
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
18
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
19 struct h_node {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
20 struct h_entry entry;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
21 struct h_node *next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
22 };
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
23
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
24 enum {MAGIC = 112};
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
25
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
26 void h_init(
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
27 Hash *h,
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
28 size_t (*hash)(const void *, size_t),
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
29 int (*cmp)(const void *, const void *),
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
30 void (*delk)(void *),
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
31 void (*delv)(void *)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
32 ) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
33 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
34
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
35 h->entries = 0;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
36 h->brk = -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
37 h->iter = -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
38 h->iterptr = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
39 h->seed = randval() * (size_t)-1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
40 h->delk = delk;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
41 h->delv = delv;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
42 assert(hash != NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
43 h->hash = hash;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
44 assert(cmp != NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
45 h->cmp = cmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
46 h->table = xmalloc(h->newsize = h->size = MAGIC, sizeof *h->table);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
47 for (i = 0; i < h->size; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
48 h->table[i] = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
49 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
50 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
51
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
52 #define DELKV(p) \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
53 do { \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
54 if (h->delk) { \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
55 h->delk((p)->entry.key); \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
56 } \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
57 if (h->delv) { \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
58 h->delv((p)->entry.value); \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
59 } \
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
60 } while (0)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
61
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
62 void h_end(Hash *h) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
63 size_t size, b;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
64
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
65 if (!h->table)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
66 return;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
67
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
68 for (b = 0, size = h->newsize; h->newsize; h->newsize--) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
69 struct h_node *p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
70
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
71 if ((p = h->table[h->newsize - 1])) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
72 ++b;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
73 for (; p; p = h->table[h->newsize - 1]) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
74 h->table[h->newsize - 1] = p->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
75 DELKV(p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
76 xfree(p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
77 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
78 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
79 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
80 xfree(h->table);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
81 h->table = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
82
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
83 if (Opt.debug & DBG_HASH) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
84 fprintf(stderr, "%s: hash[%lu/%lu/%lu]\n", Prog, (unsigned long)h->entries, (unsigned long)b, (unsigned long)size);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
85 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
86 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
87
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
88 ATTR_PURE
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
89 static size_t xclip(const Hash *h, const size_t hash_unc) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
90 size_t hash;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
91
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
92 hash = hash_unc % h->size;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
93 if (hash > h->brk) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
94 hash = hash_unc % h->newsize;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
95 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
96
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
97 return hash;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
98 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
99
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
100 #if 0
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
101 ATTR_PURE
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
102 static size_t xhash(const Hash *h, const void *key) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
103 return xclip(h, h->hash(key, h->seed));
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
104 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
105 #endif
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
106
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
107 #define XRESIZN(h) ((h)->brk + 1u)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
108 #define XSTEP(h) do { if (XRESIZN(h)) xstep(h); } while (0)
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
109
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
110 static void xstep(Hash *h) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
111 struct h_node *rev = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
112 struct h_node *p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
113 struct h_node *tmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
114
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
115 assert(h->table != NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
116
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
117 for (p = h->table[h->brk]; p; p = tmp) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
118 tmp = p->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
119 p->next = rev;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
120 rev = p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
121 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
122 h->table[h->brk--] = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
123
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
124 if (!XRESIZN(h)) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
125 h->size = h->newsize;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
126 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
127
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
128 for (p = rev; p; p = tmp) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
129 const size_t i = xclip(h, p->entry.hash);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
130 tmp = p->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
131 p->next = h->table[i];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
132 h->table[i] = p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
133 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
134 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
135
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
136 static void xincentries(Hash *h) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
137 h->entries++;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
138 if (!(XRESIZN(h)) && h->entries / h->size > 3u) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
139 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
140 h->table = xrealloc(h->table, h->newsize = h->size * 2u + 1u);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
141 for (i = h->size; i < h->newsize; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
142 h->table[i] = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
143 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
144 h->brk = h->size - 1u;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
145 xstep(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
146 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
147 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
148
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
149 int h_get(Hash *h, const void *key, void **res) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
150 XSTEP(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
151 {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
152 const size_t hash_unc = h->hash(key, h->seed);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
153 const size_t hash = xclip(h, hash_unc);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
154 struct h_node *p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
155
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
156 for (p = h->table[hash]; p; p = p->next) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
157 if (hash_unc == p->entry.hash && h->cmp(p->entry.key, key) == 0) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
158 if (res) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
159 *res = p->entry.value;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
160 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
161 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
162 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
163 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
164 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
165 return H_NOENT;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
166 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
167
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
168 int h_del(Hash *h, const void *key) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
169 XSTEP(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
170 {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
171 const size_t hash_unc = h->hash(key, h->seed);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
172 const size_t hash = xclip(h, hash_unc);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
173 struct h_node **p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
174
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
175 for (p = &h->table[hash]; *p; p = &(*p)->next) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
176 if (hash_unc == (*p)->entry.hash && h->cmp((*p)->entry.key, key) == 0) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
177 struct h_node *tmp = *p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
178 *p = (*p)->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
179 DELKV(tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
180 xfree(tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
181 h->entries--;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
182 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
183 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
184 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
185 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
186
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
187 return H_NOENT;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
188 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
189
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
190 #if 0
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
191 void h_push(Hash *h, void *key, void *val) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
192 XSTEP(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
193 {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
194 const size_t hash_unc = h->hash(key, h->seed);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
195 const size_t hash = xclip(h, hash_unc);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
196 struct h_node *p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
197
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
198 p = xmalloc(1, sizeof *p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
199 p->entry.hash = hash_unc;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
200 p->entry.key = key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
201 p->entry.value = val;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
202 p->next = h->table[hash];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
203 h->table[hash] = p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
204
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
205 xincentries(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
206 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
207 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
208 #endif
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
209
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
210 int h_put(Hash *h, void *key, void *val, int replace) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
211 XSTEP(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
212 {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
213 const size_t hash_unc = h->hash(key, h->seed);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
214 const size_t hash = xclip(h, hash_unc);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
215 struct h_node **p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
216
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
217 for (p = &h->table[hash]; *p; p = &(*p)->next) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
218 if (hash_unc == (*p)->entry.hash && h->cmp((*p)->entry.key, key) == 0) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
219 if (replace) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
220 DELKV(*p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
221 (*p)->entry.key = key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
222 (*p)->entry.value = val;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
223 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
224 } else {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
225 return H_EXIST;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
226 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
227 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
228 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
229
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
230 *p = xmalloc(1, sizeof **p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
231
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
232 (*p)->entry.hash = hash_unc;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
233 (*p)->entry.key = key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
234 (*p)->entry.value = val;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
235 (*p)->next = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
236
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
237 xincentries(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
238 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
239
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
240 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
241 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
242
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
243 void h_reset(Hash *h) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
244 h->iter = -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
245 h->iterptr = NULL;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
246 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
247
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
248 int h_nextkv(Hash *h, void **k, void **v) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
249 if (h->iterptr) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
250 *k = h->iterptr->entry.key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
251 *v = h->iterptr->entry.value;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
252 h->iterptr = h->iterptr->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
253 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
254 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
255
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
256 for (h->iter++; h->iter < h->newsize; h->iter++) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
257 if ((h->iterptr = h->table[h->iter])) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
258 *k = h->iterptr->entry.key;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
259 *v = h->iterptr->entry.value;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
260 h->iterptr = h->iterptr->next;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
261 return H_OK;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
262 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
263 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
264
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
265 h->iter = -1;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
266 return H_NOENT;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
267 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
268
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
269 #if 0
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
270 size_t (h_entries)(const Hash *h) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
271 return h_entries(h);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
272 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
273 #endif