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