1 /*
2 * Copyright (C) 2011, 2012, 2013 Citrix Systems
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #include "ns_turn_maps.h"
32
33 #include "ns_turn_ioalib.h"
34
35 #include "ns_turn_khash.h"
36
37 KHASH_MAP_INIT_INT64(3, ur_map_value_type)
38
39 #define MAGIC_HASH ((uint64_t)(0x90ABCDEFL))
40
41 struct _ur_map {
42 khash_t(3) *h;
43 uint64_t magic;
44 TURN_MUTEX_DECLARE(mutex)
45 };
46
ur_map_init(ur_map * map)47 static int ur_map_init(ur_map* map) {
48 if(map) {
49 map->h=kh_init(3);
50 if(map->h) {
51 map->magic=MAGIC_HASH;
52 TURN_MUTEX_INIT_RECURSIVE(&(map->mutex));
53 return 0;
54 }
55 }
56 return -1;
57 }
58
59 #define ur_map_valid(map) ((map) && ((map)->h) && ((map)->magic==MAGIC_HASH))
60
ur_map_create()61 ur_map* ur_map_create() {
62 ur_map *map=(ur_map*)malloc(sizeof(ur_map));
63 if(ur_map_init(map)<0) {
64 free(map);
65 return NULL;
66 }
67 return map;
68 }
69
70 /**
71 * @ret:
72 * 0 - success
73 * -1 - error
74 */
ur_map_put(ur_map * map,ur_map_key_type key,ur_map_value_type value)75 int ur_map_put(ur_map* map, ur_map_key_type key, ur_map_value_type value) {
76 if(!ur_map_valid(map)) return -1;
77 else {
78
79 int ret=0;
80 khiter_t k;
81
82 k = kh_get(3, map->h, key);
83 if(k != kh_end(map->h)) {
84 kh_del(3, map->h, k);
85 }
86
87 k = kh_put(3,map->h,key,&ret);
88
89 if (!ret) {
90 kh_del(3, map->h, k);
91 return -1;
92 }
93
94 kh_value(map->h, k) = value;
95
96 return 0;
97 }
98 }
99
100 /**
101 * @ret:
102 * 1 - success
103 * 0 - not found
104 */
ur_map_get(const ur_map * map,ur_map_key_type key,ur_map_value_type * value)105 int ur_map_get(const ur_map* map, ur_map_key_type key, ur_map_value_type *value) {
106 if(!ur_map_valid(map)) return 0;
107 else {
108
109 khiter_t k;
110
111 k = kh_get(3, map->h, key);
112 if((k != kh_end(map->h)) && kh_exist(map->h,k)) {
113 if(value) *value=kh_value(map->h,k);
114 return 1;
115 }
116
117 return 0;
118 }
119 }
120
121 /**
122 * @ret:
123 * 1 - success
124 * 0 - not found
125 */
ur_map_del(ur_map * map,ur_map_key_type key,ur_map_del_func delfunc)126 int ur_map_del(ur_map* map, ur_map_key_type key,ur_map_del_func delfunc) {
127 if(!ur_map_valid(map)) return 0;
128 else {
129
130 khiter_t k;
131
132 k = kh_get(3, map->h, key);
133 if((k != kh_end(map->h)) && kh_exist(map->h,k)) {
134 if(delfunc) {
135 delfunc(kh_value(map->h,k));
136 }
137 kh_del(3,map->h,k);
138 return 1;
139 }
140
141 return 0;
142 }
143 }
144
145 /**
146 * @ret:
147 * 1 - success
148 * 0 - not found
149 */
ur_map_exist(const ur_map * map,ur_map_key_type key)150 int ur_map_exist(const ur_map* map, ur_map_key_type key) {
151 if(!ur_map_valid(map)) return 0;
152 else {
153
154 khiter_t k;
155
156 k = kh_get(3, map->h, key);
157 if((k != kh_end(map->h)) && kh_exist(map->h,k)) {
158 return 1;
159 }
160
161 return 0;
162 }
163 }
164
ur_map_free(ur_map ** map)165 void ur_map_free(ur_map** map) {
166 if(map && ur_map_valid(*map)) {
167 {
168 static int khctest=0;
169 if(khctest)
170 kh_clear(3,(*map)->h);
171 }
172 kh_destroy(3,(*map)->h);
173 (*map)->h=NULL;
174 (*map)->magic=0;
175 TURN_MUTEX_DESTROY(&((*map)->mutex));
176 free(*map);
177 *map=NULL;
178 }
179 }
180
ur_map_size(const ur_map * map)181 size_t ur_map_size(const ur_map* map) {
182 if(ur_map_valid(map)) {
183 return kh_size(map->h);
184 } else {
185 return 0;
186 }
187 }
188
ur_map_foreach(ur_map * map,foreachcb_type func)189 int ur_map_foreach(ur_map* map, foreachcb_type func) {
190 if(map && func && ur_map_valid(map)) {
191 khiter_t k;
192 for (k = kh_begin((*map)->h); k != kh_end(map->h); ++k) {
193 if (kh_exist(map->h, k)) {
194 if(func((ur_map_key_type)(kh_key(map->h, k)),
195 (ur_map_value_type)(kh_value(map->h, k)))) {
196 return 1;
197 }
198 }
199 }
200 }
201 return 0;
202 }
203
ur_map_foreach_arg(ur_map * map,foreachcb_arg_type func,void * arg)204 int ur_map_foreach_arg(ur_map* map, foreachcb_arg_type func, void* arg) {
205 if(map && func && ur_map_valid(map)) {
206 khiter_t k;
207 for (k = kh_begin((*map)->h); k != kh_end(map->h); ++k) {
208 if (kh_exist(map->h, k)) {
209 if(func((ur_map_key_type)(kh_key(map->h, k)),
210 (ur_map_value_type)(kh_value(map->h, k)),
211 arg)
212 ) {
213 return 1;
214 }
215 }
216 }
217 }
218 return 0;
219 }
220
ur_map_lock(const ur_map * map)221 int ur_map_lock(const ur_map* map) {
222 if(ur_map_valid(map)) {
223 TURN_MUTEX_LOCK((const turn_mutex*)&(map->mutex));
224 return 0;
225 }
226 return -1;
227 }
228
ur_map_unlock(const ur_map * map)229 int ur_map_unlock(const ur_map* map) {
230 if(ur_map_valid(map)) {
231 TURN_MUTEX_UNLOCK((const turn_mutex*)&(map->mutex));
232 return 0;
233 }
234 return -1;
235 }
236
237 //////////////////// LOCAL MAPS ////////////////////////////////////
238
lm_map_init(lm_map * map)239 void lm_map_init(lm_map *map)
240 {
241 if(map) {
242 bzero(map,sizeof(lm_map));
243 }
244 }
245
246 /**
247 * @ret:
248 * 0 - success
249 * -1 - error
250 */
251
lm_map_put(lm_map * map,ur_map_key_type key,ur_map_value_type value)252 int lm_map_put(lm_map* map, ur_map_key_type key, ur_map_value_type value)
253 {
254 int ret = -1;
255 if(map && key && value) {
256
257 size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1));
258 lm_map_array *a = &(map->table[index]);
259
260 size_t i;
261
262 for(i=0;i<LM_MAP_ARRAY_SIZE;++i) {
263
264 ur_map_key_type key0 = a->main_keys[i];
265 ur_map_value_type value0 = a->main_values[i];
266
267 if(key0 == key) {
268 if(value0 == value) {
269 return 0;
270 } else {
271 return -1;
272 }
273 }
274
275 if(!key0 || !value0) {
276 a->main_keys[i] = key;
277 a->main_values[i] = value;
278 return 0;
279 }
280 }
281
282 size_t esz = a->extra_sz;
283 if(esz && a->extra_keys && a->extra_values) {
284 for(i=0;i<esz;++i) {
285 ur_map_key_type *keyp = a->extra_keys[i];
286 ur_map_value_type *valuep = a->extra_values[i];
287 if(keyp && valuep) {
288 if(!(*keyp) || !(*valuep)) {
289 *keyp = key;
290 *valuep = value;
291 return 0;
292 }
293 } else {
294 if(!(*keyp)) {
295 a->extra_keys[i] = (ur_map_key_type*)malloc(sizeof(ur_map_key_type));
296 keyp = a->extra_keys[i];
297 }
298 if(!(*valuep)) {
299 a->extra_values[i] = (ur_map_value_type*)malloc(sizeof(ur_map_value_type));
300 valuep = a->extra_values[i];
301 }
302 *keyp = key;
303 *valuep = value;
304 return 0;
305 }
306 }
307 }
308
309 size_t old_sz = esz;
310 size_t old_sz_mem = esz * sizeof(ur_map_key_type*);
311 a->extra_keys = (ur_map_key_type**)realloc(a->extra_keys,old_sz_mem + sizeof(ur_map_key_type*));
312 a->extra_keys[old_sz] = (ur_map_key_type*)malloc(sizeof(ur_map_key_type));
313 *(a->extra_keys[old_sz]) = key;
314
315 old_sz_mem = esz * sizeof(ur_map_value_type*);
316 a->extra_values = (ur_map_value_type**)realloc(a->extra_values,old_sz_mem + sizeof(ur_map_value_type*));
317 a->extra_values[old_sz] = (ur_map_value_type*)malloc(sizeof(ur_map_value_type));
318 *(a->extra_values[old_sz]) = value;
319
320 a->extra_sz += 1;
321
322 return 0;
323 }
324 return ret;
325 }
326
327 /**
328 * @ret:
329 * 1 - success
330 * 0 - not found
331 */
332
lm_map_get(const lm_map * map,ur_map_key_type key,ur_map_value_type * value)333 int lm_map_get(const lm_map* map, ur_map_key_type key, ur_map_value_type *value)
334 {
335 int ret = 0;
336 if(map && key) {
337 size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1));
338 const lm_map_array *a = &(map->table[index]);
339
340 size_t i;
341
342 for(i=0;i<LM_MAP_ARRAY_SIZE;++i) {
343
344 ur_map_key_type key0 = a->main_keys[i];
345 if((key0 == key) && a->main_values[i]) {
346 if(value) {
347 *value = a->main_values[i];
348 }
349 return 1;
350 }
351 }
352
353 size_t esz = a->extra_sz;
354 if(esz && a->extra_keys && a->extra_values) {
355 for(i=0;i<esz;++i) {
356 ur_map_key_type *keyp = a->extra_keys[i];
357 ur_map_value_type *valuep = a->extra_values[i];
358 if(keyp && valuep) {
359 if(*keyp == key) {
360 if(value)
361 *value = *valuep;
362 return 1;
363 }
364 }
365 }
366 }
367 }
368
369 return ret;
370 }
371 /**
372 * @ret:
373 * 1 - success
374 * 0 - not found
375 */
376
lm_map_del(lm_map * map,ur_map_key_type key,ur_map_del_func delfunc)377 int lm_map_del(lm_map* map, ur_map_key_type key,ur_map_del_func delfunc)
378 {
379 int ret = 0;
380
381 if(map && key) {
382 size_t index = (size_t)(key & (LM_MAP_HASH_SIZE - 1));
383 lm_map_array *a = &(map->table[index]);
384
385 size_t i;
386
387 for(i=0;i<LM_MAP_ARRAY_SIZE;++i) {
388
389 ur_map_key_type key0 = a->main_keys[i];
390
391 if((key0 == key) && a->main_values[i]) {
392 if(delfunc) {
393 delfunc(a->main_values[i]);
394 }
395 a->main_keys[i] = 0;
396 a->main_values[i] = 0;
397 return 1;
398 }
399 }
400
401 size_t esz = a->extra_sz;
402 if(esz && a->extra_keys && a->extra_values) {
403 for(i=0;i<esz;++i) {
404 ur_map_key_type *keyp = a->extra_keys[i];
405 ur_map_value_type *valuep = a->extra_values[i];
406 if(keyp && valuep) {
407 if(*keyp == key) {
408 if(delfunc)
409 delfunc(*valuep);
410 *keyp = 0;
411 *valuep = 0;
412 return 1;
413 }
414 }
415 }
416 }
417 }
418
419 return ret;
420 }
421 /**
422 * @ret:
423 * 1 - success
424 * 0 - not found
425 */
426
lm_map_exist(const lm_map * map,ur_map_key_type key)427 int lm_map_exist(const lm_map* map, ur_map_key_type key)
428 {
429 return lm_map_get(map, key, NULL);
430 }
431
lm_map_clean(lm_map * map)432 void lm_map_clean(lm_map* map)
433 {
434 size_t j;
435 for(j=0;j<LM_MAP_HASH_SIZE;++j) {
436
437 lm_map_array *a = &(map->table[j]);
438
439 size_t esz = a->extra_sz;
440 if(esz) {
441 size_t i;
442 if(a->extra_keys) {
443 for(i=0;i<esz;++i) {
444 ur_map_key_type *keyp = a->extra_keys[i];
445 if(keyp) {
446 *keyp = 0;
447 free(keyp);
448 }
449 }
450 free(a->extra_keys);
451 a->extra_keys = NULL;
452 }
453 if(a->extra_values) {
454 for(i=0;i<esz;++i) {
455 ur_map_value_type *valuep = a->extra_values[i];
456 if(valuep) {
457 *valuep = 0;
458 free(valuep);
459 }
460 }
461 free(a->extra_values);
462 a->extra_values = NULL;
463 }
464 }
465 }
466
467 lm_map_init(map);
468 }
469
lm_map_size(const lm_map * map)470 size_t lm_map_size(const lm_map* map)
471 {
472 size_t ret = 0;
473
474 if(map) {
475
476 size_t i;
477
478 for(i=0;i<LM_MAP_HASH_SIZE;++i) {
479
480 const lm_map_array *a = &(map->table[i]);
481
482 size_t j;
483
484 for(j=0;j<LM_MAP_ARRAY_SIZE;++j) {
485 if(a->main_keys[j] && a->main_values[j]) {
486 ++ret;
487 }
488 }
489
490 size_t esz = a->extra_sz;
491 if(esz && a->extra_values && a->extra_keys) {
492 for(j=0;j<esz;++j) {
493 if(*(a->extra_keys[j]) && *(a->extra_values[j])) {
494 ++ret;
495 }
496 }
497 }
498 }
499 }
500
501 return ret;
502 }
503
lm_map_foreach(lm_map * map,foreachcb_type func)504 int lm_map_foreach(lm_map* map, foreachcb_type func)
505 {
506 size_t ret = 0;
507
508 if(map) {
509
510 size_t i;
511
512 for(i=0;i<LM_MAP_HASH_SIZE;++i) {
513
514 lm_map_array *a = &(map->table[i]);
515
516 size_t j;
517
518 for(j=0;j<LM_MAP_ARRAY_SIZE;++j) {
519 if(a->main_keys[j] && a->main_values[j]) {
520 if(func((ur_map_key_type)a->main_keys[j],
521 (ur_map_value_type)a->main_values[j])) {
522 return 1;
523 }
524 }
525 }
526
527 size_t esz = a->extra_sz;
528 if(esz && a->extra_values && a->extra_keys) {
529 for(j=0;j<esz;++j) {
530 if(*(a->extra_keys[j]) && *(a->extra_values[j])) {
531 if(func((ur_map_key_type)*(a->extra_keys[j]),
532 (ur_map_value_type)*(a->extra_values[j]))) {
533 return 1;
534 }
535 }
536 }
537 }
538 }
539 }
540
541 return ret;
542 }
543
lm_map_foreach_arg(lm_map * map,foreachcb_arg_type func,void * arg)544 int lm_map_foreach_arg(lm_map* map, foreachcb_arg_type func, void* arg)
545 {
546 size_t ret = 0;
547
548 if(map) {
549
550 size_t i;
551
552 for(i=0;i<LM_MAP_HASH_SIZE;++i) {
553
554 lm_map_array *a = &(map->table[i]);
555
556 size_t j;
557
558 for(j=0;j<LM_MAP_ARRAY_SIZE;++j) {
559 if(a->main_keys[j] && a->main_values[j]) {
560 if(func((ur_map_key_type)a->main_keys[j],
561 (ur_map_value_type)a->main_values[j],
562 arg)) {
563 return 1;
564 }
565 }
566 }
567
568 size_t esz = a->extra_sz;
569 if(esz && a->extra_values && a->extra_keys) {
570 for(j=0;j<esz;++j) {
571 if(*(a->extra_keys[j]) && *(a->extra_values[j])) {
572 if(func((ur_map_key_type)*(a->extra_keys[j]),
573 (ur_map_value_type)*(a->extra_values[j]),
574 arg)) {
575 return 1;
576 }
577 }
578 }
579 }
580 }
581 }
582
583 return ret;
584 }
585
586 //////////////////// ADDR LISTS ///////////////////////////////////
587
addr_list_free(addr_list_header * slh)588 static void addr_list_free(addr_list_header* slh) {
589 if(slh) {
590 if(slh->extra_list) {
591 free(slh->extra_list);
592 }
593 bzero(slh,sizeof(addr_list_header));
594 }
595 }
596
addr_list_add(addr_list_header * slh,const ioa_addr * key,ur_addr_map_value_type value)597 static void addr_list_add(addr_list_header* slh, const ioa_addr* key, ur_addr_map_value_type value) {
598
599 if(!key || !value) return;
600
601 addr_elem *elem = NULL;
602 size_t i;
603
604 for(i=0;i<ADDR_ARRAY_SIZE;++i) {
605 if(!(slh->main_list[i].value)) {
606 elem = &(slh->main_list[i]);
607 break;
608 }
609 }
610
611 if(!elem && slh->extra_list) {
612 for(i=0;i<slh->extra_sz;++i) {
613 if(!(slh->extra_list[i].value)) {
614 elem = &(slh->extra_list[i]);
615 break;
616 }
617 }
618 }
619
620 if(!elem) {
621 size_t old_sz = slh->extra_sz;
622 size_t old_sz_mem = old_sz * sizeof(addr_elem);
623 slh->extra_list = (addr_elem*)realloc(slh->extra_list, old_sz_mem + sizeof(addr_elem));
624 elem = &(slh->extra_list[old_sz]);
625 slh->extra_sz += 1;
626 }
627
628 addr_cpy(&(elem->key),key);
629 elem->value=value;
630 }
631
addr_list_remove(addr_list_header * slh,const ioa_addr * key,ur_addr_map_func delfunc,int * counter)632 static void addr_list_remove(addr_list_header* slh, const ioa_addr* key,
633 ur_addr_map_func delfunc, int *counter) {
634 if(!slh || !key) return;
635
636 if(counter)
637 *counter = 0;
638
639 size_t i;
640
641 for(i=0;i<ADDR_ARRAY_SIZE;++i) {
642 addr_elem *elem=&(slh->main_list[i]);
643 if(elem->value) {
644 if(addr_eq(&(elem->key),key)) {
645 if(delfunc && elem->value)
646 delfunc(elem->value);
647 elem->value = 0;
648 if(counter) {
649 *counter += 1;
650 }
651 }
652 }
653 }
654
655 if(slh->extra_list) {
656 for(i=0;i<slh->extra_sz;++i) {
657 addr_elem *elem=&(slh->extra_list[i]);
658 if(elem->value) {
659 if(addr_eq(&(elem->key),key)) {
660 if(delfunc && elem->value)
661 delfunc(elem->value);
662 elem->value = 0;
663 if(counter) {
664 *counter += 1;
665 }
666 }
667 }
668 }
669 }
670 }
671
addr_list_foreach(addr_list_header * slh,ur_addr_map_func func)672 static void addr_list_foreach(addr_list_header* slh, ur_addr_map_func func) {
673 if(slh && func) {
674
675 size_t i;
676
677 for(i=0;i<ADDR_ARRAY_SIZE;++i) {
678 addr_elem *elem=&(slh->main_list[i]);
679 if(elem->value) {
680 func(elem->value);
681 }
682 }
683
684 if(slh->extra_list) {
685 for(i=0;i<slh->extra_sz;++i) {
686 addr_elem *elem=&(slh->extra_list[i]);
687 if(elem->value) {
688 func(elem->value);
689 }
690 }
691 }
692 }
693 }
694
addr_list_num_elements(const addr_list_header * slh)695 static size_t addr_list_num_elements(const addr_list_header* slh) {
696
697 size_t ret = 0;
698
699 if (slh) {
700
701 size_t i;
702
703 for (i = 0; i < ADDR_ARRAY_SIZE; ++i) {
704 const addr_elem *elem = &(slh->main_list[i]);
705 if (elem->value) {
706 ++ret;
707 }
708 }
709
710 if (slh->extra_list) {
711 for (i = 0; i < slh->extra_sz; ++i) {
712 addr_elem *elem = &(slh->extra_list[i]);
713 if (elem->value) {
714 ++ret;
715 }
716 }
717 }
718 }
719
720 return ret;
721 }
722
addr_list_size(const addr_list_header * slh)723 static size_t addr_list_size(const addr_list_header* slh) {
724
725 size_t ret = 0;
726
727 if (slh) {
728
729 ret += ADDR_ARRAY_SIZE;
730
731 ret += slh->extra_sz;
732 }
733
734 return ret;
735 }
736
addr_list_get(addr_list_header * slh,const ioa_addr * key)737 static addr_elem* addr_list_get(addr_list_header* slh, const ioa_addr* key) {
738
739 if(!slh || !key) return NULL;
740
741 size_t i;
742
743 for(i=0;i<ADDR_ARRAY_SIZE;++i) {
744 addr_elem *elem=&(slh->main_list[i]);
745 if(elem->value) {
746 if(addr_eq(&(elem->key),key)) {
747 return elem;
748 }
749 }
750 }
751
752 if(slh->extra_list) {
753 for(i=0;i<slh->extra_sz;++i) {
754 addr_elem *elem=&(slh->extra_list[i]);
755 if(elem->value) {
756 if(addr_eq(&(elem->key),key)) {
757 return elem;
758 }
759 }
760 }
761 }
762
763 return NULL;
764 }
765
addr_list_get_const(const addr_list_header * slh,const ioa_addr * key)766 static const addr_elem* addr_list_get_const(const addr_list_header* slh, const ioa_addr* key) {
767
768 if(!slh || !key) return NULL;
769
770 size_t i;
771
772 for(i=0;i<ADDR_ARRAY_SIZE;++i) {
773 const addr_elem *elem=&(slh->main_list[i]);
774 if(elem->value) {
775 if(addr_eq(&(elem->key),key)) {
776 return elem;
777 }
778 }
779 }
780
781 if(slh->extra_list) {
782 for(i=0;i<slh->extra_sz;++i) {
783 const addr_elem *elem=&(slh->extra_list[i]);
784 if(elem->value) {
785 if(addr_eq(&(elem->key),key)) {
786 return elem;
787 }
788 }
789 }
790 }
791
792 return NULL;
793 }
794
795 ////////// ADDR MAPS ////////////////////////////////////////////
796
797 #define addr_map_index(key) (addr_hash((key)) & (ADDR_MAP_SIZE - 1))
798
799 #define get_addr_list_header(map, key) (&((map)->lists[addr_map_index((key))]))
800
801 #define ur_addr_map_valid(map) ((map) && ((map)->magic==MAGIC_HASH))
802
ur_addr_map_init(ur_addr_map * map)803 void ur_addr_map_init(ur_addr_map* map) {
804 if(map) {
805 bzero(map,sizeof(ur_addr_map));
806 map->magic=MAGIC_HASH;
807 }
808 }
809
ur_addr_map_clean(ur_addr_map * map)810 void ur_addr_map_clean(ur_addr_map* map) {
811 if(map && ur_addr_map_valid(map)) {
812 uint32_t i=0;
813 for(i=0;i<ADDR_MAP_SIZE;i++) {
814 addr_list_free(&(map->lists[i]));
815 }
816 bzero(map,sizeof(ur_addr_map));
817 }
818 }
819
820 /**
821 * @ret:
822 * 0 - success
823 * -1 - error
824 * if the addr key exists, the value is updated.
825 */
ur_addr_map_put(ur_addr_map * map,ioa_addr * key,ur_addr_map_value_type value)826 int ur_addr_map_put(ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type value) {
827
828 if(!ur_addr_map_valid(map)) return -1;
829
830 else {
831
832 addr_list_header* slh = get_addr_list_header(map, key);
833
834 addr_elem* elem = addr_list_get(slh, key);
835 if(elem) {
836 elem->value=value;
837 } else {
838 addr_list_add(slh,key,value);
839 }
840
841 return 0;
842 }
843 }
844
845 /**
846 * @ret:
847 * 1 - success
848 * 0 - not found
849 */
ur_addr_map_get(const ur_addr_map * map,ioa_addr * key,ur_addr_map_value_type * value)850 int ur_addr_map_get(const ur_addr_map* map, ioa_addr* key, ur_addr_map_value_type *value) {
851
852 if(!ur_addr_map_valid(map)) return 0;
853
854 else {
855
856 const addr_list_header* slh = get_addr_list_header(map, key);
857
858 const addr_elem *elem = addr_list_get_const(slh, key);
859 if(elem) {
860 if(value) *value=elem->value;
861 return 1;
862 }
863
864 return 0;
865 }
866 }
867
868 /**
869 * @ret:
870 * 1 - success
871 * 0 - not found
872 */
ur_addr_map_del(ur_addr_map * map,ioa_addr * key,ur_addr_map_func delfunc)873 int ur_addr_map_del(ur_addr_map* map, ioa_addr* key,ur_addr_map_func delfunc) {
874
875 if(!ur_addr_map_valid(map)) return 0;
876
877 else {
878
879 addr_list_header* slh = get_addr_list_header(map, key);
880
881 int counter=0;
882
883 addr_list_remove(slh, key, delfunc, &counter);
884
885 return (counter>0);
886 }
887 }
888
889 /**
890 * @ret:
891 * 1 - success
892 * 0 - not found
893 */
ur_addr_map_foreach(ur_addr_map * map,ur_addr_map_func func)894 void ur_addr_map_foreach(ur_addr_map* map, ur_addr_map_func func) {
895
896 if(ur_addr_map_valid(map)) {
897
898 uint32_t i=0;
899 for(i=0;i<ADDR_MAP_SIZE;i++) {
900
901 addr_list_header* slh = &(map->lists[i]);
902
903 addr_list_foreach(slh, func);
904 }
905 }
906 }
907
ur_addr_map_num_elements(const ur_addr_map * map)908 size_t ur_addr_map_num_elements(const ur_addr_map* map) {
909
910 size_t ret = 0;
911
912 if (ur_addr_map_valid(map)) {
913 uint32_t i = 0;
914 for (i = 0; i < ADDR_MAP_SIZE; i++) {
915
916 const addr_list_header* slh = &(map->lists[i]);
917
918 ret += addr_list_num_elements(slh);
919 }
920 }
921
922 return ret;
923 }
924
ur_addr_map_size(const ur_addr_map * map)925 size_t ur_addr_map_size(const ur_addr_map* map) {
926
927 size_t ret = 0;
928
929 if (ur_addr_map_valid(map)) {
930 uint32_t i = 0;
931 for (i = 0; i < ADDR_MAP_SIZE; i++) {
932
933 const addr_list_header* slh = &(map->lists[i]);
934
935 ret += addr_list_size(slh);
936 }
937 }
938
939 return ret;
940 }
941
942 //////////////////// STRING LISTS ///////////////////////////////////
943
944 typedef struct _string_list {
945 struct _string_list* next;
946 } string_list;
947
948 typedef struct _string_elem {
949 string_list list;
950 ur_string_map_key_type key;
951 uint32_t key_size;
952 ur_string_map_value_type value;
953 } string_elem;
954
955 typedef struct _string_list_header {
956 string_list *list;
957 } string_list_header;
958
string_list_size(const string_list * sl)959 static size_t string_list_size(const string_list *sl) {
960 if(!sl) return 0;
961 return 1+string_list_size(sl->next);
962 }
963
string_list_free(string_list_header * slh,ur_string_map_func del_value_func)964 static void string_list_free(string_list_header* slh, ur_string_map_func del_value_func) {
965 if(slh) {
966 string_list* list=slh->list;
967 while(list) {
968 string_elem *elem=(string_elem*)list;
969 string_list* tail=elem->list.next;
970 if(elem->key) free(elem->key);
971 if(del_value_func && elem->value)
972 del_value_func(elem->value);
973 free(elem);
974 list=tail;
975 }
976 slh->list=NULL;
977 }
978 }
979
string_list_add(string_list * sl,const ur_string_map_key_type key,ur_string_map_value_type value)980 static string_list* string_list_add(string_list* sl, const ur_string_map_key_type key, ur_string_map_value_type value) {
981 if(!key) return sl;
982 string_elem *elem=(string_elem*)malloc(sizeof(string_elem));
983 elem->list.next=sl;
984 elem->key_size = strlen(key)+1;
985 elem->key=(char*)malloc(elem->key_size);
986 bcopy(key,elem->key,elem->key_size);
987 elem->value=value;
988 return &(elem->list);
989 }
990
string_list_remove(string_list * sl,const ur_string_map_key_type key,ur_string_map_func del_value_func,int * counter)991 static string_list* string_list_remove(string_list* sl, const ur_string_map_key_type key,
992 ur_string_map_func del_value_func, int *counter) {
993 if(!sl || !key) return sl;
994 string_elem *elem=(string_elem*)sl;
995 string_list* tail=elem->list.next;
996 if(strcmp(elem->key,key)==0) {
997 free(elem->key);
998 if(del_value_func)
999 del_value_func(elem->value);
1000 free(elem);
1001 if(counter) *counter+=1;
1002 sl=string_list_remove(tail, key, del_value_func, counter);
1003 } else {
1004 elem->list.next=string_list_remove(tail,key,del_value_func,counter);
1005 }
1006 return sl;
1007 }
1008
string_list_get(string_list * sl,const ur_string_map_key_type key)1009 static string_elem* string_list_get(string_list* sl, const ur_string_map_key_type key) {
1010
1011 if(!sl || !key) return NULL;
1012
1013 string_elem *elem=(string_elem*)sl;
1014 if(strcmp(elem->key,key)==0) {
1015 return elem;
1016 } else {
1017 return string_list_get(elem->list.next, key);
1018 }
1019 }
1020
1021 ////////// STRING MAPS ////////////////////////////////////////////
1022
1023 #define STRING_MAP_SIZE (1024)
1024
1025 struct _ur_string_map {
1026 string_list_header lists[STRING_MAP_SIZE];
1027 uint64_t magic;
1028 ur_string_map_func del_value_func;
1029 TURN_MUTEX_DECLARE(mutex)
1030 };
1031
string_hash(const ur_string_map_key_type key)1032 static uint32_t string_hash(const ur_string_map_key_type key) {
1033
1034 uint8_t *str=(uint8_t*)key;
1035
1036 uint32_t hash = 0;
1037 int c = 0;
1038
1039 while ((c = *str++))
1040 hash = c + (hash << 6) + (hash << 16) - hash;
1041
1042 return hash;
1043 }
1044
string_map_index(const ur_string_map_key_type key)1045 static int string_map_index(const ur_string_map_key_type key) {
1046 return (int)(string_hash(key) % STRING_MAP_SIZE);
1047 }
1048
get_string_list_header(ur_string_map * map,const ur_string_map_key_type key)1049 static string_list_header* get_string_list_header(ur_string_map *map, const ur_string_map_key_type key) {
1050 return &(map->lists[string_map_index(key)]);
1051 }
1052
ur_string_map_init(ur_string_map * map)1053 static int ur_string_map_init(ur_string_map* map) {
1054 if(map) {
1055 bzero(map,sizeof(ur_string_map));
1056 map->magic=MAGIC_HASH;
1057
1058 TURN_MUTEX_INIT_RECURSIVE(&(map->mutex));
1059
1060 return 0;
1061 }
1062 return -1;
1063 }
1064
ur_string_map_valid(const ur_string_map * map)1065 static int ur_string_map_valid(const ur_string_map *map) {
1066 return (map && map->magic==MAGIC_HASH);
1067 }
1068
ur_string_map_create(ur_string_map_func del_value_func)1069 ur_string_map* ur_string_map_create(ur_string_map_func del_value_func) {
1070 ur_string_map *map=(ur_string_map*)malloc(sizeof(ur_string_map));
1071 if(ur_string_map_init(map)<0) {
1072 free(map);
1073 return NULL;
1074 }
1075 map->del_value_func = del_value_func;
1076 return map;
1077 }
1078
1079 /**
1080 * @ret:
1081 * 0 - success
1082 * -1 - error
1083 * if the string key exists, and the value is different, return error.
1084 */
ur_string_map_put(ur_string_map * map,const ur_string_map_key_type key,ur_string_map_value_type value)1085 int ur_string_map_put(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type value) {
1086
1087 if(!ur_string_map_valid(map)) return -1;
1088
1089 else {
1090
1091 string_list_header* slh = get_string_list_header(map, key);
1092
1093 string_elem *elem = string_list_get(slh->list, key);
1094 if(elem) {
1095 if(elem->value != value) {
1096 if(map->del_value_func)
1097 map->del_value_func(elem->value);
1098 elem->value = value;
1099 }
1100 return 0;
1101 }
1102
1103 slh->list=string_list_add(slh->list,key,value);
1104
1105 return 0;
1106 }
1107 }
1108
1109 /**
1110 * @ret:
1111 * 1 - success
1112 * 0 - not found
1113 */
ur_string_map_get(ur_string_map * map,const ur_string_map_key_type key,ur_string_map_value_type * value)1114 int ur_string_map_get(ur_string_map* map, const ur_string_map_key_type key, ur_string_map_value_type *value) {
1115
1116 if(!ur_string_map_valid(map)) return 0;
1117
1118 else {
1119
1120 string_list_header* slh = get_string_list_header(map, key);
1121 string_elem *elem = string_list_get(slh->list, key);
1122 if(elem) {
1123 if(value) *value=elem->value;
1124 return 1;
1125 } else {
1126 return 0;
1127 }
1128 }
1129 }
1130
1131 /**
1132 * @ret:
1133 * 1 - success
1134 * 0 - not found
1135 */
ur_string_map_del(ur_string_map * map,const ur_string_map_key_type key)1136 int ur_string_map_del(ur_string_map* map, const ur_string_map_key_type key) {
1137
1138 if(!ur_string_map_valid(map)) return 0;
1139
1140 else {
1141
1142 string_list_header* slh = get_string_list_header(map, key);
1143
1144 int counter=0;
1145
1146 slh->list=string_list_remove(slh->list, key, map->del_value_func, &counter);
1147
1148 return (counter>0);
1149 }
1150 }
1151
ur_string_map_clean(ur_string_map * map)1152 void ur_string_map_clean(ur_string_map* map) {
1153 if (ur_string_map_valid(map)) {
1154 int i = 0;
1155 for (i = 0; i < STRING_MAP_SIZE; i++) {
1156 string_list_free(&(map->lists[i]), map->del_value_func);
1157 }
1158 }
1159 }
1160
ur_string_map_free(ur_string_map ** map)1161 void ur_string_map_free(ur_string_map** map) {
1162 if(map && ur_string_map_valid(*map)) {
1163 int i=0;
1164 for(i=0;i<STRING_MAP_SIZE;i++) {
1165 string_list_free(&((*map)->lists[i]),(*map)->del_value_func);
1166 }
1167 (*map)->magic=0;
1168 TURN_MUTEX_DESTROY(&((*map)->mutex));
1169 free(*map);
1170 *map=NULL;
1171 }
1172 }
1173
ur_string_map_size(const ur_string_map * map)1174 size_t ur_string_map_size(const ur_string_map* map) {
1175 if(ur_string_map_valid(map)) {
1176 size_t ret=0;
1177 int i=0;
1178 for(i=0;i<STRING_MAP_SIZE;i++) {
1179 ret+=string_list_size(map->lists[i].list);
1180 }
1181 return ret;
1182 } else {
1183 return 0;
1184 }
1185 }
1186
ur_string_map_lock(const ur_string_map * map)1187 int ur_string_map_lock(const ur_string_map* map) {
1188 if(ur_string_map_valid(map)) {
1189 TURN_MUTEX_LOCK((const turn_mutex*)&(map->mutex));
1190 return 0;
1191 }
1192 return -1;
1193 }
1194
ur_string_map_unlock(const ur_string_map * map)1195 int ur_string_map_unlock(const ur_string_map* map) {
1196 if(ur_string_map_valid(map)) {
1197 TURN_MUTEX_UNLOCK((const turn_mutex*)&(map->mutex));
1198 return 0;
1199 }
1200 return -1;
1201 }
1202
1203 ////////////////////////////////////////////////////////////////
1204