PAPI 7.1.0.0
Loading...
Searching...
No Matches
cuda/htable.h
Go to the documentation of this file.
1
8#ifndef __HTABLE_H__
9#define __HTABLE_H__
10
11#include <string.h>
12#include <inttypes.h>
13#include "papi.h"
14#include "papi_internal.h"
15#include "papi_memory.h"
16
17#define HTABLE_SUCCESS ( 0)
18#define HTABLE_ENOVAL (-1)
19#define HTABLE_EINVAL (-2)
20#define HTABLE_ENOMEM (-3)
21
22#define HTABLE_NEEDS_TO_GROW(table) (table->size > 0 && table->capacity / table->size < 2)
23#define HTABLE_NEEDS_TO_SHRINK(table) (table->size > 0 && table->capacity / table->size > 8)
24
26 char *key;
27 void *val;
29};
30
31struct hash_table {
32 uint32_t capacity;
33 uint32_t size;
35};
36
37static uint64_t hash_func(const char *);
38
39static int create_table(uint64_t, struct hash_table **);
40static int destroy_table(struct hash_table *);
41static int rehash_table(struct hash_table *, struct hash_table *);
42static int move_table(struct hash_table *, struct hash_table *);
43static int check_n_resize_table(struct hash_table *);
44static int destroy_table_entries(struct hash_table *);
45
46static int create_table_entry(const char *, void *,
47 struct hash_table_entry **);
48static int destroy_table_entry(struct hash_table_entry *);
49static int insert_table_entry(struct hash_table *, struct hash_table_entry *);
50static int delete_table_entry(struct hash_table *, struct hash_table_entry *);
51static int find_table_entry(struct hash_table *, const char *,
52 struct hash_table_entry **);
53
54static inline int
56{
57 int htable_errno = HTABLE_SUCCESS;
58
59#define HTABLE_MIN_SIZE (8)
60 struct hash_table *table = NULL;
61 htable_errno = create_table(HTABLE_MIN_SIZE, &table);
62 if (htable_errno != HTABLE_SUCCESS) {
63 goto fn_fail;
64 }
65
66 *handle = table;
67
68 fn_exit:
69 return htable_errno;
70 fn_fail:
71 *handle = NULL;
72 goto fn_exit;
73}
74
75static inline int
77{
78 int htable_errno = HTABLE_SUCCESS;
79 struct hash_table *table = (struct hash_table *) handle;
80
81 if (table == NULL) {
82 return HTABLE_EINVAL;
83 }
84
86 destroy_table(table);
87
88 return htable_errno;
89}
90
91static inline int
92htable_insert(void *handle, const char *key, void *in)
93{
94 int htable_errno = HTABLE_SUCCESS;
95 struct hash_table *table = (struct hash_table *) handle;
96
97 if (table == NULL || key == NULL) {
98 return HTABLE_EINVAL;
99 }
100
101 struct hash_table_entry *entry = NULL;
102 htable_errno = find_table_entry(table, key, &entry);
103 if (htable_errno == HTABLE_SUCCESS) {
104 entry->val = in;
105 goto fn_exit;
106 }
107
108 htable_errno = create_table_entry(key, in, &entry);
109 if (htable_errno != HTABLE_SUCCESS) {
110 goto fn_fail;
111 }
112
113 htable_errno = insert_table_entry(table, entry);
114 if (htable_errno != HTABLE_SUCCESS) {
115 goto fn_fail;
116 }
117
118 htable_errno = check_n_resize_table(table);
119
120 fn_exit:
121 return htable_errno;
122 fn_fail:
123 if (entry) {
124 papi_free(entry);
125 }
126 goto fn_exit;
127}
128
129static inline int
130htable_delete(void *handle, const char *key)
131{
132 int htable_errno = HTABLE_SUCCESS;
133 struct hash_table *table = (struct hash_table *) handle;
134
135 if (table == NULL || key == NULL) {
136 return HTABLE_EINVAL;
137 }
138
139 struct hash_table_entry *entry = NULL;
140 htable_errno = find_table_entry(table, key, &entry);
141 if (htable_errno != HTABLE_SUCCESS) {
142 return htable_errno;
143 }
144
145 entry->val = NULL;
146
147 htable_errno = delete_table_entry(table, entry);
148 if (htable_errno != HTABLE_SUCCESS) {
149 return htable_errno;
150 }
151
152 htable_errno = destroy_table_entry(entry);
153 if (htable_errno != HTABLE_SUCCESS) {
154 return htable_errno;
155 }
156
157 return check_n_resize_table(table);
158}
159
160static inline int
161htable_find(void *handle, const char *key, void **out)
162{
163 int htable_errno = HTABLE_SUCCESS;
164 struct hash_table *table = (struct hash_table *) handle;
165
166 if (table == NULL || key == NULL || out == NULL) {
167 return HTABLE_EINVAL;
168 }
169
170 struct hash_table_entry *entry = NULL;
171 htable_errno = find_table_entry(table, key, &entry);
172 if (htable_errno != HTABLE_SUCCESS) {
173 return htable_errno;
174 }
175
176 *out = entry->val;
177 return htable_errno;
178}
179
183uint64_t
184hash_func(const char *string)
185{
186 uint64_t hash = 5381;
187 int c;
188 while ((c = *string++)) {
189 hash = ((hash << 5) + hash) + c;
190 }
191 return hash;
192}
193
194int
195create_table(uint64_t size, struct hash_table **table)
196{
197 int htable_errno = HTABLE_SUCCESS;
198
199 *table = papi_calloc(1, sizeof(**table));
200 if (table == NULL) {
201 htable_errno = HTABLE_ENOMEM;
202 goto fn_exit;
203 }
204
205 (*table)->buckets = papi_calloc(size, sizeof(*(*table)->buckets));
206 if ((*table)->buckets == NULL) {
207 htable_errno = HTABLE_ENOMEM;
208 goto fn_exit;
209 }
210
211 (*table)->capacity = size;
212
213 fn_exit:
214 return htable_errno;
215}
216
217int
219{
220 int htable_errno = HTABLE_SUCCESS;
221
222 if (table && table->buckets) {
223 papi_free(table->buckets);
224 }
225
226 if (table) {
227 papi_free(table);
228 }
229
230 return htable_errno;
231}
232
233int
234rehash_table(struct hash_table *old_table, struct hash_table *new_table)
235{
236 uint64_t old_id;
237 for (old_id = 0; old_id < old_table->capacity; ++old_id) {
238 struct hash_table_entry *entry = old_table->buckets[old_id];
239 struct hash_table_entry *next;
240 while (entry) {
241 next = entry->next;
242 delete_table_entry(old_table, entry);
243 insert_table_entry(new_table, entry);
244 entry = next;
245 }
246 }
247
248 return HTABLE_SUCCESS;
249}
250
251int
252move_table(struct hash_table *new_table, struct hash_table *old_table)
253{
254 int htable_errno = HTABLE_SUCCESS;
255 struct hash_table_entry **old_buckets = old_table->buckets;
256
257 old_table->capacity = new_table->capacity;
258 old_table->size = new_table->size;
259 old_table->buckets = new_table->buckets;
260 new_table->buckets = NULL;
261 papi_free(old_buckets);
262
263 return htable_errno;
264}
265
266int
268{
269 int htable_errno = HTABLE_SUCCESS;
270 uint64_t i;
271
272 for (i = 0; i < table->capacity; ++i) {
273 struct hash_table_entry *entry = table->buckets[i];
274 struct hash_table_entry *tmp = NULL;
275
276 while (entry) {
277 tmp = entry;
278 entry = entry->next;
279 delete_table_entry(table, tmp);
281 }
282 }
283
284 return htable_errno;
285}
286int
288{
289 int htable_errno = HTABLE_SUCCESS;
290 struct hash_table *new_table = NULL;
291 char resize =
292 (HTABLE_NEEDS_TO_GROW(table) << 1) | HTABLE_NEEDS_TO_SHRINK(table);
293
294 if (resize) {
295 uint64_t new_capacity = (resize & 0x2) ?
296 table->capacity * 2 : table->capacity / 2;
297 htable_errno = create_table(new_capacity, &new_table);
298 if (htable_errno != HTABLE_SUCCESS) {
299 goto fn_fail;
300 }
301
302 htable_errno = rehash_table(table, new_table);
303 if (htable_errno != HTABLE_SUCCESS) {
304 goto fn_fail;
305 }
306
307 move_table(new_table, table);
308 destroy_table(new_table);
309 }
310
311 fn_exit:
312 return htable_errno;
313 fn_fail:
314 if (new_table) {
315 destroy_table(new_table);
316 }
317 goto fn_exit;
318}
319
320int
321create_table_entry(const char *key, void *val, struct hash_table_entry **entry)
322{
323 int htable_errno = HTABLE_SUCCESS;
324
325 *entry = papi_calloc(1, sizeof(**entry));
326 if (*entry == NULL) {
327 return HTABLE_ENOMEM;
328 }
329 (*entry)->key = strdup(key);
330 (*entry)->val = val;
331 (*entry)->next = NULL;
332
333 return htable_errno;
334}
335
336int
338{
339 int htable_errno = HTABLE_SUCCESS;
340 papi_free(entry->key);
341 papi_free(entry);
342 return htable_errno;
343}
344
345int
346insert_table_entry(struct hash_table *table, struct hash_table_entry *entry)
347{
348 int htable_errno = HTABLE_SUCCESS;
349
350 uint64_t id = hash_func(entry->key) % table->capacity;
351
352 if (table->buckets[id]) {
353 entry->next = table->buckets[id];
354 }
355
356 table->buckets[id] = entry;
357 ++table->size;
358
359 return htable_errno;
360}
361
362int
363delete_table_entry(struct hash_table *table, struct hash_table_entry *entry)
364{
365 int htable_errno = HTABLE_SUCCESS;
366
367 uint64_t id = hash_func(entry->key) % table->capacity;
368
369 if (table->buckets[id] == entry) {
370 table->buckets[id] = entry->next;
371 entry->next = NULL;
372 goto fn_exit;
373 }
374
375 struct hash_table_entry *prev = table->buckets[id];
376 struct hash_table_entry *curr = table->buckets[id]->next;
377
378 while (curr) {
379 if (curr == entry) {
380 prev->next = curr->next;
381 curr->next = NULL;
382 break;
383 }
384 prev = prev->next;
385 curr = curr->next;
386 }
387
388 fn_exit:
389 --table->size;
390 return htable_errno;
391}
392
393int
394find_table_entry(struct hash_table *table, const char *key,
395 struct hash_table_entry **entry)
396{
397 int htable_errno;
398
399 uint64_t id = hash_func(key) % table->capacity;
400 struct hash_table_entry *head = table->buckets[id];
401 if (head == NULL) {
402 htable_errno = HTABLE_ENOVAL;
403 goto fn_exit;
404 }
405
406 struct hash_table_entry *curr = head;
407 while (curr && strcmp(curr->key, key)) {
408 curr = curr->next;
409 }
410
411 *entry = curr;
412 htable_errno = (curr) ? HTABLE_SUCCESS : HTABLE_ENOVAL;
413
414 fn_exit:
415 return htable_errno;
416}
417#endif /* __HTABLE_H__ */
static papi_handle_t handle
Definition: Gamum.c:21
double tmp
int i
static int find_table_entry(struct hash_table *, const char *, struct hash_table_entry **)
Definition: cuda/htable.h:394
static uint64_t hash_func(const char *)
Definition: cuda/htable.h:184
static int destroy_table(struct hash_table *)
Definition: cuda/htable.h:218
static int rehash_table(struct hash_table *, struct hash_table *)
Definition: cuda/htable.h:234
static int create_table_entry(const char *, void *, struct hash_table_entry **)
Definition: cuda/htable.h:321
static int destroy_table_entry(struct hash_table_entry *)
Definition: cuda/htable.h:337
static int htable_insert(void *handle, const char *key, void *in)
Definition: cuda/htable.h:92
#define HTABLE_MIN_SIZE
static int htable_delete(void *handle, const char *key)
Definition: cuda/htable.h:130
static int insert_table_entry(struct hash_table *, struct hash_table_entry *)
Definition: cuda/htable.h:346
static int delete_table_entry(struct hash_table *, struct hash_table_entry *)
Definition: cuda/htable.h:363
#define HTABLE_ENOVAL
Definition: cuda/htable.h:18
static int htable_shutdown(void *handle)
Definition: cuda/htable.h:76
static int create_table(uint64_t, struct hash_table **)
Definition: cuda/htable.h:195
#define HTABLE_SUCCESS
Definition: cuda/htable.h:17
#define HTABLE_ENOMEM
Definition: cuda/htable.h:20
static int check_n_resize_table(struct hash_table *)
Definition: cuda/htable.h:287
#define HTABLE_EINVAL
Definition: cuda/htable.h:19
#define HTABLE_NEEDS_TO_SHRINK(table)
Definition: cuda/htable.h:23
#define HTABLE_NEEDS_TO_GROW(table)
Definition: cuda/htable.h:22
static int htable_find(void *handle, const char *key, void **out)
Definition: cuda/htable.h:161
static int move_table(struct hash_table *, struct hash_table *)
Definition: cuda/htable.h:252
static int htable_init(void **handle)
Definition: cuda/htable.h:55
static int destroy_table_entries(struct hash_table *)
Definition: cuda/htable.h:267
static pthread_key_t key
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
Return codes and api definitions.
#define papi_calloc(a, b)
Definition: papi_memory.h:37
#define papi_free(a)
Definition: papi_memory.h:35
Definition: cuda/htable.h:25
struct hash_table_entry * next
Definition: cuda/htable.h:28
void * val
Definition: cuda/htable.h:27
char * key
Definition: cuda/htable.h:26
struct hash_table_entry ** buckets
Definition: cuda/htable.h:34
uint32_t capacity
Definition: cuda/htable.h:32
uint32_t size
Definition: cuda/htable.h:33