00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libts.h"
00025 #include "P_RecUtils.h"
00026 #include "P_RecCore.h"
00027 #include "P_RecTree.h"
00028
00029
00030
00031
00032 void
00033 RecRecordInit(RecRecord *r)
00034 {
00035 ink_zero(*r);
00036 rec_mutex_init(&(r->lock), NULL);
00037 }
00038
00039 void
00040 RecRecordFree(RecRecord *r)
00041 {
00042 rec_mutex_destroy(&(r->lock));
00043 }
00044
00045
00046
00047
00048 RecRecord*
00049 RecAlloc(RecT rec_type, const char *name, RecDataT data_type)
00050 {
00051 if (g_num_records >= REC_MAX_RECORDS) {
00052 Warning("too many stats/configs, please increase REC_MAX_RECORDS or rebuild with --with_max_api_stats=<n>");
00053 return NULL;
00054 }
00055
00056 int i = ink_atomic_increment(&g_num_records, 1);
00057 RecRecord *r = &(g_records[i]);
00058
00059 RecRecordInit(r);
00060 r->rec_type = rec_type;
00061 r->name = ats_strdup(name);
00062 r->order = i;
00063 r->data_type = data_type;
00064
00065 g_records_tree->rec_tree_insert(r->name);
00066
00067 return r;
00068 }
00069
00070
00071
00072
00073
00074 void
00075 RecDataClear(RecDataT data_type, RecData * data)
00076 {
00077 if ((data_type == RECD_STRING) && (data->rec_string)) {
00078 ats_free(data->rec_string);
00079 }
00080 memset(data, 0, sizeof(RecData));
00081 }
00082
00083 void
00084 RecDataSetMax(RecDataT type, RecData * data)
00085 {
00086 switch (type) {
00087 #if defined(STAT_PROCESSOR)
00088 case RECD_FX:
00089 #endif
00090 case RECD_INT:
00091 case RECD_COUNTER:
00092 data->rec_int = INT64_MAX;
00093 break;
00094 #if defined(STAT_PROCESSOR)
00095 case RECD_CONST:
00096 #endif
00097 case RECD_FLOAT:
00098 data->rec_float = FLT_MAX;
00099 break;
00100 default:
00101 Fatal("unsupport type:%d\n", type);
00102 }
00103 }
00104
00105 void
00106 RecDataSetMin(RecDataT type, RecData * data)
00107 {
00108 switch (type) {
00109 #if defined(STAT_PROCESSOR)
00110 case RECD_FX:
00111 #endif
00112 case RECD_INT:
00113 case RECD_COUNTER:
00114 data->rec_int = INT64_MIN;
00115 break;
00116 #if defined(STAT_PROCESSOR)
00117 case RECD_CONST:
00118 #endif
00119 case RECD_FLOAT:
00120 data->rec_float = FLT_MIN;
00121 break;
00122 default:
00123 Fatal("unsupport type:%d\n", type);
00124 }
00125 }
00126
00127
00128
00129
00130 bool
00131 RecDataSet(RecDataT data_type, RecData * data_dst, RecData * data_src)
00132 {
00133 bool rec_set = false;
00134
00135 switch (data_type) {
00136 case RECD_STRING:
00137 if (data_src->rec_string == NULL) {
00138 if (data_dst->rec_string != NULL) {
00139 ats_free(data_dst->rec_string);
00140 data_dst->rec_string = NULL;
00141 rec_set = true;
00142 }
00143 } else if (((data_dst->rec_string) && (strcmp(data_dst->rec_string, data_src->rec_string) != 0)) ||
00144 ((data_dst->rec_string == NULL) && (data_src->rec_string != NULL))) {
00145 if (data_dst->rec_string)
00146 ats_free(data_dst->rec_string);
00147
00148 data_dst->rec_string = ats_strdup(data_src->rec_string);
00149 rec_set = true;
00150
00151 char *end = data_dst->rec_string + strlen(data_dst->rec_string) - 1;
00152
00153 while (end >= data_dst->rec_string && isspace(*end))
00154 end--;
00155 *(end + 1) = '\0';
00156 }
00157 break;
00158 case RECD_INT:
00159 if (data_dst->rec_int != data_src->rec_int) {
00160 data_dst->rec_int = data_src->rec_int;
00161 rec_set = true;
00162 }
00163 break;
00164 case RECD_FLOAT:
00165 if (data_dst->rec_float != data_src->rec_float) {
00166 data_dst->rec_float = data_src->rec_float;
00167 rec_set = true;
00168 }
00169 break;
00170 case RECD_COUNTER:
00171 if (data_dst->rec_counter != data_src->rec_counter) {
00172 data_dst->rec_counter = data_src->rec_counter;
00173 rec_set = true;
00174 }
00175 break;
00176 default:
00177 ink_assert(!"Wrong RECD type!");
00178 }
00179 return rec_set;
00180
00181 }
00182
00183 int
00184 RecDataCmp(RecDataT type, RecData left, RecData right)
00185 {
00186 switch (type) {
00187 #if defined(STAT_PROCESSOR)
00188 case RECD_FX:
00189 #endif
00190 case RECD_INT:
00191 case RECD_COUNTER:
00192 if (left.rec_int > right.rec_int)
00193 return 1;
00194 else if (left.rec_int == right.rec_int)
00195 return 0;
00196 else
00197 return -1;
00198 #if defined(STAT_PROCESSOR)
00199 case RECD_CONST:
00200 #endif
00201 case RECD_FLOAT:
00202 if (left.rec_float > right.rec_float)
00203 return 1;
00204 else if (left.rec_float == right.rec_float)
00205 return 0;
00206 else
00207 return -1;
00208 default:
00209 Fatal("unsupport type:%d\n", type);
00210 return 0;
00211 }
00212 }
00213
00214 RecData
00215 RecDataAdd(RecDataT type, RecData left, RecData right)
00216 {
00217 RecData val;
00218 memset(&val, 0, sizeof(val));
00219
00220 switch (type) {
00221 #if defined(STAT_PROCESSOR)
00222 case RECD_FX:
00223 #endif
00224 case RECD_INT:
00225 case RECD_COUNTER:
00226 val.rec_int = left.rec_int + right.rec_int;
00227 break;
00228 #if defined(STAT_PROCESSOR)
00229 case RECD_CONST:
00230 #endif
00231 case RECD_FLOAT:
00232 val.rec_float = left.rec_float + right.rec_float;
00233 break;
00234 default:
00235 Fatal("unsupported type:%d\n", type);
00236 break;
00237 }
00238 return val;
00239 }
00240
00241 RecData
00242 RecDataSub(RecDataT type, RecData left, RecData right)
00243 {
00244 RecData val;
00245 memset(&val, 0, sizeof(val));
00246
00247 switch (type) {
00248 #if defined(STAT_PROCESSOR)
00249 case RECD_FX:
00250 #endif
00251 case RECD_INT:
00252 case RECD_COUNTER:
00253 val.rec_int = left.rec_int - right.rec_int;
00254 break;
00255 #if defined(STAT_PROCESSOR)
00256 case RECD_CONST:
00257 #endif
00258 case RECD_FLOAT:
00259 val.rec_float = left.rec_float - right.rec_float;
00260 break;
00261 default:
00262 Fatal("unsupported type:%d\n", type);
00263 break;
00264 }
00265 return val;
00266 }
00267
00268 RecData
00269 RecDataMul(RecDataT type, RecData left, RecData right)
00270 {
00271 RecData val;
00272 memset(&val, 0, sizeof(val));
00273
00274 switch (type) {
00275 #if defined(STAT_PROCESSOR)
00276 case RECD_FX:
00277 #endif
00278 case RECD_INT:
00279 case RECD_COUNTER:
00280 val.rec_int = left.rec_int * right.rec_int;
00281 break;
00282 #if defined(STAT_PROCESSOR)
00283 case RECD_CONST:
00284 #endif
00285 case RECD_FLOAT:
00286 val.rec_float = left.rec_float * right.rec_float;
00287 break;
00288 default:
00289 Fatal("unsupported type:%d\n", type);
00290 break;
00291 }
00292 return val;
00293 }
00294
00295 RecData
00296 RecDataDiv(RecDataT type, RecData left, RecData right)
00297 {
00298 RecData val;
00299 memset(&val, 0, sizeof(val));
00300
00301 switch (type) {
00302 #if defined(STAT_PROCESSOR)
00303 case RECD_FX:
00304 #endif
00305 case RECD_INT:
00306 case RECD_COUNTER:
00307 val.rec_int = left.rec_int / right.rec_int;
00308 break;
00309 #if defined(STAT_PROCESSOR)
00310 case RECD_CONST:
00311 #endif
00312 case RECD_FLOAT:
00313 val.rec_float = left.rec_float / right.rec_float;
00314 break;
00315 default:
00316 Fatal("unsupported type:%d\n", type);
00317 break;
00318 }
00319 return val;
00320 }
00321
00322
00323
00324
00325 bool
00326 RecDataSetFromInk64(RecDataT data_type, RecData * data_dst, int64_t data_int64)
00327 {
00328 switch (data_type) {
00329 #if defined(STAT_PROCESSOR)
00330 case RECD_FX:
00331 #endif
00332 case RECD_INT:
00333 data_dst->rec_int = data_int64;
00334 break;
00335 #if defined(STAT_PROCESSOR)
00336 case RECD_CONST:
00337 #endif
00338 case RECD_FLOAT:
00339 data_dst->rec_float = (float) (data_int64);
00340 break;
00341 case RECD_STRING:
00342 {
00343 char buf[32 + 1];
00344
00345 ats_free(data_dst->rec_string);
00346 snprintf(buf, 32, "%" PRId64 "", data_int64);
00347 data_dst->rec_string = ats_strdup(buf);
00348 break;
00349 }
00350 case RECD_COUNTER:
00351 data_dst->rec_counter = data_int64;
00352 break;
00353 default:
00354 ink_assert(!"Unexpected RecD type");
00355 return false;
00356 }
00357
00358 return true;
00359 }
00360
00361
00362
00363
00364
00365 bool
00366 RecDataSetFromFloat(RecDataT data_type, RecData * data_dst, float data_float)
00367 {
00368 switch (data_type) {
00369 #if defined(STAT_PROCESSOR)
00370 case RECD_FX:
00371 #endif
00372 case RECD_INT:
00373 data_dst->rec_int = (RecInt) data_float;
00374 break;
00375 #if defined(STAT_PROCESSOR)
00376 case RECD_CONST:
00377 #endif
00378 case RECD_FLOAT:
00379 data_dst->rec_float = (float) (data_float);
00380 break;
00381 case RECD_STRING:
00382 {
00383 char buf[32 + 1];
00384
00385 ats_free(data_dst->rec_string);
00386 snprintf(buf, 32, "%f", data_float);
00387 data_dst->rec_string = ats_strdup(buf);
00388 break;
00389 }
00390 case RECD_COUNTER:
00391 data_dst->rec_counter = (RecCounter) data_float;
00392 break;
00393 default:
00394 ink_assert(!"Unexpected RecD type");
00395 return false;
00396 }
00397
00398 return true;
00399 }
00400
00401
00402
00403
00404
00405 bool
00406 RecDataSetFromString(RecDataT data_type, RecData * data_dst, const char *data_string)
00407 {
00408 bool rec_set;
00409 RecData data_src;
00410
00411 switch (data_type) {
00412 #if defined(STAT_PROCESSOR)
00413 case RECD_FX:
00414 #endif
00415 case RECD_INT:
00416 data_src.rec_int = ink_atoi64(data_string);
00417 break;
00418 #if defined(STAT_PROCESSOR)
00419 case RECD_CONST:
00420 #endif
00421 case RECD_FLOAT:
00422 data_src.rec_float = atof(data_string);
00423 break;
00424 case RECD_STRING:
00425 if (strcmp((data_string), "NULL") == 0) {
00426 data_src.rec_string = NULL;
00427 } else {
00428
00429 data_src.rec_string = (char *)data_string;
00430 }
00431 break;
00432 case RECD_COUNTER:
00433 data_src.rec_counter = ink_atoi64(data_string);
00434 break;
00435 default:
00436 ink_assert(!"Unexpected RecD type");
00437 return false;
00438 }
00439 rec_set = RecDataSet(data_type, data_dst, &data_src);
00440
00441 return rec_set;
00442 }
00443