sort based on the weight of the gws */
| 2960 | |
| 2961 | /* sort based on the weight of the gws */ |
| 2962 | static int weight_based_sort(pgw_list_t *pgwl, int size, unsigned short *idx) |
| 2963 | { |
| 2964 | static unsigned short *running_sum = NULL; |
| 2965 | static unsigned short sum_buf_size = 0; |
| 2966 | |
| 2967 | unsigned int i, first, weight_sum, rand_no; |
| 2968 | |
| 2969 | /* populate the index array */ |
| 2970 | for( i=0 ; i<size ; i++ ) idx[i] = i; |
| 2971 | first = 0; |
| 2972 | |
| 2973 | while (size-first>1) { |
| 2974 | resize_dr_sort_buffer( running_sum, sum_buf_size, size, err); |
| 2975 | /* calculate the running sum */ |
| 2976 | for( i=first,weight_sum=0 ; i<size ; i++ ) { |
| 2977 | weight_sum += pgwl[ idx[i] ].weight ; |
| 2978 | running_sum[i] = weight_sum; |
| 2979 | LM_DBG("elem %d, weight=%d, sum=%d\n",i, |
| 2980 | pgwl[ idx[i] ].weight, running_sum[i]); |
| 2981 | } |
| 2982 | if (weight_sum) { |
| 2983 | /* randomly select number */ |
| 2984 | rand_no = (unsigned int)(weight_sum*((double)rand()/((double)1+RAND_MAX))); |
| 2985 | LM_DBG("random number is %d\n",rand_no); |
| 2986 | /* select the element */ |
| 2987 | for( i=first ; i<size ; i++ ) |
| 2988 | if (running_sum[i]>rand_no) break; |
| 2989 | if (i==size) { |
| 2990 | LM_CRIT("bug in weight sort, first=%u, size=%u, rand_no=%u, total weight=%u\n", |
| 2991 | first, size, rand_no, weight_sum); |
| 2992 | for(i=first; i<size;i++) |
| 2993 | LM_CRIT("i %d, idx %u, weight %u, running sum %u\n", |
| 2994 | i, idx[i], pgwl[idx[i]].weight, running_sum[i]); |
| 2995 | /* try to recover here by picking the last gw */ |
| 2996 | i = size - 1; |
| 2997 | // return -1; |
| 2998 | } |
| 2999 | } else { |
| 3000 | /* all remaining gateways have weight 0, treat them as equal |
| 3001 | and randomly select one with uniform distribution */ |
| 3002 | i = first + (unsigned int)((size - first) * ((double)rand() / ((double)RAND_MAX + 1.0))); |
| 3003 | } |
| 3004 | LM_DBG("selecting element %d with weight %d\n", |
| 3005 | idx[i], pgwl[ idx[i] ].weight); |
| 3006 | /* "i" is the selected element : swap it with first position and |
| 3007 | retake alg without first elem */ |
| 3008 | rand_no = idx[i]; |
| 3009 | idx[i] = idx[first]; |
| 3010 | idx[first] = rand_no; |
| 3011 | first ++; |
| 3012 | } |
| 3013 | |
| 3014 | return 0; |
| 3015 | err: |
| 3016 | return -1; |
| 3017 | } |
| 3018 | |
| 3019 |
no outgoing calls
no test coverage detected