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