|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/connect/ncbi_lb.c |
source navigation diff markup identifier search freetext search file search |
1 /* $Id: ncbi_lb.c,v 1.12 2008/02/14 16:25:55 kazimird Exp $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 * Author: Anton Lavrentiev
26 *
27 * File Description:
28 * Generic LB API
29 *
30 */
31
32 #include "ncbi_lb.h"
33 #include "ncbi_priv.h"
34 #include <assert.h>
35 #include <stdlib.h>
36
37
38 #define NCBI_USE_ERRCODE_X Connect_LB
39
40
41 size_t LB_Select(SERV_ITER iter, void* data,
42 FGetCandidate get_candidate, double bonus)
43 {
44 double total = 0.0, access = 0.0, point = 0.0, p = 0.0, status = 0.0;
45 const SSERV_Info* info;
46 SLB_Candidate* cand;
47 int/*bool*/ fixed;
48 size_t i = 0, n;
49
50 assert(bonus >= 1.0);
51 assert(iter && get_candidate);
52 if (iter->ismask || iter->ok_down || iter->ok_suppressed)
53 return 0/*first entry (DISPD: probably) fits*/;
54 fixed = 0/*false*/;
55 for (n = 0; ; n++) {
56 int/*bool*/ latch;
57 if (!(cand = get_candidate(data, n)))
58 break;
59 info = cand->info;
60 status = cand->status;
61 latch = iter->host && iter->host == info->host
62 && (!iter->port || iter->port == info->port);
63 if (latch || (!fixed && !iter->host &&
64 info->locl && info->coef < 0.0)) {
65 if (fixed < latch) {
66 fixed = latch;
67 access = point = 0.0;
68 }
69 if (iter->pref || info->coef <= 0.0) {
70 status *= bonus;
71 if (access < status && (iter->pref || info->coef < 0.0)) {
72 access = status; /* always take the largest */
73 point = total + status; /* mark this local server */
74 p = -info->coef; /* NB: may end up negative */
75 i = n;
76 }
77 } else /* assert(latch); */
78 status *= info->coef;
79 }
80 total += status;
81 cand->status = total;
82 #ifdef NCBI_LB_DEBUG
83 {{
84 char addr[80];
85 const char* name = SERV_NameOfInfo(info);
86 SOCK_HostPortToString(info->host, info->port, addr, sizeof(addr));
87 CORE_LOGF(eLOG_Note,
88 ("%d: %s %s\tR=%lf\tS=%lf\tT=%lf\tA=%lf\tP=%lf",
89 (int) n, name, addr, info->rate, status, total,
90 access, point));
91 }}
92 #endif /*NCBI_LB_DEBUG*/
93 }
94 assert(n > 0);
95
96 if (fixed && iter->pref < 0.0) {
97 /* fixed preference */
98 cand = get_candidate(data, i);
99 status = access;
100 } else {
101 if (iter->pref > 0.0) {
102 if (point > 0.0 && access > 0.0 && total != access) {
103 p = SERV_Preference(iter->pref, access/total, n);
104 #ifdef NCBI_LB_DEBUG
105 CORE_LOGF(eLOG_Note,
106 ("(P=%lf,\tA=%lf,\tT=%lf,\tA/T=%lf,\tN=%d) "
107 "-> P=%lf",
108 iter->pref, access, total, access/total,
109 (int) n, p));
110 #endif /*NCBI_LB_DEBUG*/
111 status = total * p;
112 p = total * (1.0 - p) / (total - access);
113 for (i = 0; i < n; i++) {
114 cand = get_candidate(data, i);
115 if (point <= cand->status)
116 cand->status = p * (cand->status - access) + status;
117 else
118 cand->status *= p;
119 }
120 #ifdef NCBI_LB_DEBUG
121 status = 0.0;
122 for (i = 0; i < n; i++) {
123 char addr[80];
124 cand = get_candidate(data, i);
125 info = cand->info;
126 p = cand->status - status;
127 status = cand->status;
128 SOCK_HostPortToString(info->host, info->port,
129 addr, sizeof(addr));
130 CORE_LOGF(eLOG_Note,
131 ("%d: %s %s\tS=%lf\t%.2lf%%",
132 (int) i, SERV_NameOfInfo(info), addr,
133 p, p / total * 100.0));
134 }
135 #endif /*NCBI_LB_DEBUG*/
136 }
137 point = -1.0;
138 }
139
140 /* We take pre-chosen local server only if its status is not less
141 than p% of the average remaining status; otherwise, we ignore
142 the server, and apply the generic procedure by random seeding.*/
143 if (point <= 0.0 || access * (n - 1) < p * 0.01 * (total - access)) {
144 point = (total * rand()) / (double) RAND_MAX;
145 #ifdef NCBI_LB_DEBUG
146 CORE_LOGF(eLOG_Note, ("P = %lf", point));
147 #endif /*NCBI_LB_DEBUG*/
148 }
149
150 total = 0.0;
151 for (i = 0; i < n; i++) {
152 cand = get_candidate(data, i);
153 assert(cand);
154 if (point <= cand->status) {
155 status = cand->status - total;
156 break;
157 }
158 total = cand->status;
159 }
160 }
161
162 assert(cand && i < n);
163 cand->status = status;
164
165 return i;
166 }
167 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |