ROSS
hash-quadratic.c
Go to the documentation of this file.
1#include <ross.h>
2#ifdef AVL_TREE
3#include "avl_tree.h"
4#endif /* AVL_TREE */
5
6#ifndef AVL_TREE
7static void rehash(tw_hash * hash_t, int pe);
8static int find_entry(tw_event ** hash_t, tw_event * event, int hash_size, int pe);
9static void insert(tw_event ** hash_t, tw_event * event, int hash_size);
10static int find_empty(tw_event ** hash_t, tw_event * event, int hash_size);
11static int next_prime(int ptst);
12static tw_event **allocate_table(int hash_size);
13static int hash_(tw_eventid event_id, int hash_size);
14#endif
15static int is_prime(int ptst);
16tw_event *hash_search(tw_event ** hash_t, tw_event *evt, int size);
17
18void hash_print(tw_hash * h);
19
20static unsigned int ncpu = 1;
21unsigned int g_tw_hash_size = 31;
22
23#ifndef AVL_TREE
24int
25hash_(tw_eventid event_id, int hash_size)
26{
27 return event_id % hash_size;
28}
29#endif
30
31void *
33{
34#ifdef AVL_TREE
35 unsigned int i;
36 AvlTree avl_list;
37
38 g_tw_pe->avl_tree_size = 0;
39
41 avl_list = (AvlTree) tw_calloc(TW_LOC, "avl tree", sizeof(struct avlNode), g_tw_avl_node_count);
42
43 for (i = 0; i < g_tw_avl_node_count - 1; i++) {
44 avl_list[i].next = &avl_list[i + 1];
45 }
46 avl_list[i].next = NULL;
47
48 g_tw_pe->avl_list_head = &avl_list[0];
49
50 return NULL;
51#else
52 tw_hash *h;
53 unsigned int pi;
54
55 ncpu = tw_nnodes();
56 h = (tw_hash *) tw_calloc(TW_LOC, "tw_hash", sizeof(tw_hash), 1);
57
58 if (!h)
59 tw_error(TW_LOC, "Cannot allocate tw_hash.");
60
61 h->num_stored = (int *) tw_calloc(TW_LOC, "tw_hash", sizeof(int) * ncpu, 1);
62 h->hash_sizes = (unsigned int *) tw_calloc(TW_LOC, "tw_hash", sizeof(int) * ncpu, 1);
63 h->incoming = (tw_event ***) tw_calloc(TW_LOC, "tw_hash", sizeof(tw_event *)* ncpu, 1);
64
67
68 for (pi = 0; pi < ncpu; pi++)
69 {
70 h->num_stored[pi] = 0;
72 h->incoming[pi] = allocate_table(h->hash_sizes[pi]);
73 }
74
75 return (void *) h;
76#endif
77}
78
79void
80tw_hash_insert(void *h, tw_event * event, long pe)
81{
82#ifdef AVL_TREE
83 (void) h;
84 (void) pe;
85 tw_clock start;
86
87 g_tw_pe->avl_tree_size++;
88
89 start = tw_clock_read();
90 avlInsert(&event->dest_lp->kp->avl_tree, event);
91 g_tw_pe->stats.s_avl += tw_clock_read() - start;
92#else
93 tw_hash *hash_t;
94
95 hash_t = (tw_hash *) h;
96
97 insert(hash_t->incoming[pe], event, hash_t->hash_sizes[pe]);
98
99 (hash_t->num_stored[pe])++;
100 if (hash_t->num_stored[pe] > floor(hash_t->hash_sizes[pe] * MAX_FRACTION))
101 {
102 rehash(hash_t, pe);
103 }
104#endif
105}
106
107#ifndef AVL_TREE
108void
109insert(tw_event ** hash_t, tw_event * event, int hash_size)
110{
111 int key = 0;
112
113 key = find_empty(hash_t, event, hash_size);
114 hash_t[key] = event;
115}
116
117void
118rehash(tw_hash * hash_t, int pe)
119{
120 int old_size;
121 int old_stored;
122 int i;
123 tw_event **old_list;
124
125 old_stored = hash_t->num_stored[pe];
126 old_list = hash_t->incoming[pe];
127 old_size = hash_t->hash_sizes[pe];
128
129 hash_t->num_stored[pe] = 0;
130 hash_t->hash_sizes[pe] = next_prime(hash_t->hash_sizes[pe]);
131 hash_t->incoming[pe] = allocate_table(hash_t->hash_sizes[pe]);
132
133 for (i = 0; i < old_size; i++)
134 {
135 if (old_list[i] != NULL)
136 {
137 insert(hash_t->incoming[pe], old_list[i], hash_t->hash_sizes[pe]);
138 (hash_t->num_stored[pe])++;
139 }
140 }
141
142 if(old_stored != hash_t->num_stored[pe])
143 tw_error(TW_LOC, "Did not rehash properly!");
144
145#if VERIFY_HASH_QUAD
146 printf("\nHASH TABLE RESIZED: old size = %d, new size = %d \n\n", old_size,
147 hash_t->hash_sizes[pe]);
148#endif
149}
150
151int
152find_empty(tw_event ** hash_t, tw_event * event, int hash_size)
153{
154 unsigned int i;
155 int key;
156
157 i = 0;
158 key = hash_(event->event_id, hash_size);
159
160 if(0 > key)
161 tw_error(TW_LOC, "here!");
162
163 while (hash_t[key])
164 {
165 key += 2 * (++i) - 1;
166 if (key >= hash_size)
167 key -= hash_size;
168 }
169
170 return key;
171}
172
173int
174find_entry(tw_event ** hash_t, tw_event * event, int hash_size, int pe)
175{
176 unsigned int i;
177 int key;
178
179 i = 0;
180 key = hash_(event->event_id, hash_size);
181
182 while (hash_t[key] == NULL || event->event_id != hash_t[key]->event_id)
183 {
184 key += 2 * (++i) - 1;
185 if (key >= hash_size)
186 key -= hash_size;
187
188 if (key > hash_size)
189 {
190 tw_error(TW_LOC, "Cannot find event in hash table: PE %d, key %d, size %d\n",
191 pe, key, hash_size);
192 }
193 }
194
195 return key;
196}
197
198tw_event **
199allocate_table(int hash_size)
200{
201 return (tw_event **) tw_calloc(TW_LOC, "tw_hash", sizeof(tw_event *) * hash_size, 1);
202}
203#endif
204
205tw_event *
206tw_hash_remove(void *h, tw_event * event, long pe)
207{
208#if AVL_TREE
209 (void) h;
210 (void) pe;
211 tw_event *ret;
212 tw_clock start;
213
214 g_tw_pe->avl_tree_size--;
215
216 start = tw_clock_read();
217 ret = avlDelete(&event->dest_lp->kp->avl_tree, event);
218 g_tw_pe->stats.s_avl += tw_clock_read() - start;
219 return ret;
220#else
221 tw_hash *hash_t = (tw_hash *) h;
222 tw_event *ret_event;
223 int key;
224
225 if(pe > tw_nnodes() - 1)
226 tw_error(TW_LOC, "bad pe id");
227
228 key = find_entry(hash_t->incoming[pe], event, hash_t->hash_sizes[pe], pe);
229 ret_event = hash_t->incoming[pe][key];
230
231 hash_t->incoming[pe][key] = NULL;
232 (hash_t->num_stored[pe])--;
233
234 return ret_event;
235#endif
236}
237
238int
239next_prime(int ptst)
240{
241
242 ptst = ptst * 2 + 1;
243
244 if (is_prime(ptst))
245 {
246 // printf("%d is prime.\n", ptst);
247 return ptst;
248 }
249 // printf("Searching forward for next prime... ");
250 while (!is_prime(ptst))
251 ptst += 2;
252
253 // printf("found %d.\n",ptst);
254
255 return ptst;
256}
257
258int
259is_prime(int ptst)
260{
261 long pmaxseek, a;
262 int prim_found;
263
264 if (ptst % 2 == 0)
265 return 0;
266
267 prim_found = 1;
268 pmaxseek = (long)sqrt((double)ptst) + 1;
269
270 for (a = 3; a <= pmaxseek; a++, a++)
271 {
272 if (!(ptst % a))
273 {
274 prim_found = 0;
275 break;
276 }
277 }
278
279 return prim_found;
280}
281
282tw_event *
283hash_search(tw_event ** hash_t, tw_event *evt, int size)
284{
285 int j, empty;
286 tw_event *e;
287
288 for (empty = 0, j = 0; j < size; j++)
289 {
290 e = hash_t[j];
291
292 if (e && (e->event_id == evt->event_id))
293 {
294 printf("Found event in hash: %d\n", j);
295 return e;
296 } else
297 empty++;
298 }
299
300 printf("%ld: HASH has %d empty cells. \n", g_tw_mynode, empty);
301
302 return NULL;
303}
304
305void
307{
308 unsigned int i, j, empty;
309 unsigned int *sizes = h->hash_sizes;
310 int *stored = h->num_stored;
311 tw_event **hash_t;
312 tw_event *e;
313
314 for (i = 0; i < ncpu; i++)
315 {
316 printf("PE %d: \n", i);
317 printf("table size: %d \n", sizes[i]);
318 printf("num_stored: %d \n\n", stored[i]);
319
320 hash_t = h->incoming[i];
321
322 for (empty = 0, j = 0; j < sizes[i]; j++)
323 {
324 e = hash_t[j];
325
326 if (e)
327 {
328 //printf("recv_ts = %f \n", e->recv_ts);
329 //printf("%d: %ld \n\n", j, e->event_id);
330 } else
331 empty++;
332 }
333 printf("PE %d has %d empty cells. \n", i, empty);
334 }
335}
tw_pe * pe
Definition avl_tree.c:10
tw_event * avlDelete(AvlTree *t, tw_event *key)
Definition avl_tree.c:270
void avlInsert(AvlTree *t, tw_event *key)
Definition avl_tree.c:172
static tw_clock tw_clock_read(void)
Definition aarch64.h:8
uint64_t tw_clock
Definition aarch64.h:6
unsigned int g_tw_hash_size
#define MAX_FRACTION
unsigned tw_nnodes(void)
void * tw_calloc(const char *file, int line, const char *for_who, size_t e_sz, size_t n)
Definition tw-util.c:206
tw_pe * g_tw_pe
Definition ross-global.c:79
void tw_error(const char *file, int line, const char *fmt,...)
Definition tw-util.c:77
tw_peid g_tw_mynode
Definition ross-global.c:92
uint32_t g_tw_avl_node_count
Definition ross-global.c:41
#define TW_LOC
struct avlNode * AvlTree
Definition ross-types.h:28
unsigned int tw_eventid
Definition ross-types.h:56
tw_event * hash_search(tw_event **hash_t, tw_event *evt, int size)
int next_prime(int ptst)
void tw_hash_insert(void *h, tw_event *event, long pe)
void * tw_hash_create()
static unsigned int ncpu
static int is_prime(int ptst)
tw_event * tw_hash_remove(void *h, tw_event *event, long pe)
void hash_print(tw_hash *h)
struct avlNode * next
Definition avl_tree.h:14
Event Stucture.
Definition ross-types.h:277
tw_lp * dest_lp
Destination LP ID.
Definition ross-types.h:312
tw_eventid event_id
Unique id assigned by src_lp->pe if remote.
Definition ross-types.h:291
unsigned int * hash_sizes
int * num_stored
tw_event *** incoming
AvlTree avl_tree
Definition ross-types.h:393
tw_kp * kp
kp – Kernel process that we belong to (must match pe).
Definition ross-types.h:345