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