[tools] / trunk / publicdemo / sipp / stat.cpp Repository:
ViewVC logotype

View of /trunk/publicdemo/sipp/stat.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 70 - (download) (annotate)
Thu May 5 20:35:33 2011 UTC (2 years ago) by jhermanski
File size: 60630 byte(s)
Package all media, etc. needed for Public demo system into one tree
    1 /*
    2  *  This program is free software; you can redistribute it and/or modify
    3  *  it under the terms of the GNU General Public License as published by
    4  *  the Free Software Foundation; either version 2 of the License, or
    5  *  (at your option) any later version.
    6  *
    7  *  This program is distributed in the hope that it will be useful,
    8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   10  *  GNU General Public License for more details.
   11  *
   12  *  You should have received a copy of the GNU General Public License
   13  *  along with this program; if not, write to the Free Software
   14  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   15  *
   16  *  Authors : Benjamin GAUTHIER - 24 Mar 2004
   17  *            Joseph BANINO
   18  *            Olivier JACQUES
   19  *            Richard GAYRAUD
   20  *            From Hewlett Packard Company.
   21  *            Wolfgang Beck
   22  *
   23  */
   24 
   25 #include <iostream>
   26 #include <fstream>
   27 #include <iomanip>
   28 
   29 #include "sipp.hpp"
   30 #include "scenario.hpp"
   31 #include "screen.hpp"
   32 #ifdef HAVE_GSL
   33 #include <gsl/gsl_rng.h>
   34 #include <gsl/gsl_randist.h>
   35 #include <gsl/gsl_cdf.h>
   36 #endif
   37 
   38 /*
   39 ** Local definitions (macros)
   40 */
   41 
   42 /*
   43 ** Warning! All DISPLAY_ macros must be called where f FILE is
   44 **          defined. This is to allow printing to stdout or a file.
   45 */
   46 #define DISPLAY_LINE()\
   47   fprintf(f," ------------------------------------------------------------------------------ \r\n")
   48 #define DISPLAY_DLINE()\
   49   fprintf(f,"================================================================================\r\n")
   50 #define DISPLAY_CROSS_LINE()\
   51   fprintf(f,"-------------------------+---------------------------+--------------------------\r\n")
   52 
   53 #define DISPLAY_HEADER()\
   54   fprintf(f,"  Counter Name           | Periodic value            | Cumulative value\r\n")
   55 #define DISPLAY_TXT_COL(T1, V1, V2)\
   56   fprintf(f,"  %-22.22s | %-25.25s |", T1, V1); fprintf(f," %-24.24s \r\n", V2)
   57 #define DISPLAY_VAL_RATEF_COL(T1, V1, V2)\
   58   fprintf(f,"  %-22.22s | %8.3f cps              | %8.3f cps             \r\n", T1, V1, V2)
   59 #define DISPLAY_2VAL(T1, V1, V2)\
   60   fprintf(f,"  %-22.22s | %8llu                  | %8llu                 \r\n", T1, V1, V2)
   61 #define DISPLAY_CUMUL(T1, V1)\
   62   fprintf(f,"  %-22.22s |                           | %8llu                 \r\n", T1, V1)
   63 #define DISPLAY_PERIO(T1, V1)\
   64   fprintf(f,"  %-22.22s | %8llu                  |                          \r\n", T1, V1)
   65 #define DISPLAY_VALF(T1, V1)\
   66   fprintf(f,"  %-22.22s | %8.3f ms                                          \r\n", T1, V1)
   67 #define DISPLAY_VAL_RATEF(T1, V1)\
   68   fprintf(f,"  %-22.22s | %8.3f cps                                         \r\n", T1, V1)
   69 #define DISPLAY_VAL_RATE(T1, V1)\
   70   fprintf(f,"  %-22.22s | %8d cps                                         \r\n", T1, V1)
   71 #define DISPLAY_VAL(T1, V1)\
   72   fprintf(f,"  %-22.22s : %8d                                             \r\n", T1, V1)
   73 #define DISPLAY_2VALF(T1, V1, T2, V2)\
   74   fprintf(f,"  %-22.22s : %8.2f  | %-7.7s : %8.2f                       \r\n", T1, V1, T2, V2)
   75 #define DISPLAY_3VAL(T1, V1, T2, V2, T3, V3)\
   76   fprintf(f,"  %-22.22s : %8d  | %-7.7s : %8d  | %-12.12s : %5d \r\n", T1, V1, T2, V2, T3, V3)
   77 #define DISPLAY_3VALF(T1, V1, T2, V2, T3, V3)\
   78   fprintf(f,"  %-22.22s : %8.3f  | %-7.7s : %8.3f  | %-12.12s : %5.1f \r\n", T1, V1, T2, V2, T3, V3)
   79 #define DISPLAY_TXT(T1, V1)\
   80   fprintf(f,"  %-22.22s | %-52.52s \r\n", T1, V1)
   81 #define DISPLAY_INFO(T1)\
   82   fprintf(f,"  %-77.77s \r\n", T1)
   83 #define DISPLAY_REPART(T1, T2, V1)\
   84   fprintf(f,"    %8d ms <= n <  %8d ms : %10d  %-29.29s \r\n", T1, T2, V1, "")
   85 #define DISPLAY_LAST_REPART(T1, V1)\
   86   fprintf(f,"    %14.14s n >= %8d ms : %10d  %-29.29s \r\n", "", T1, V1, "")
   87 
   88 #define RESET_COUNTERS(PT)\
   89   memset (PT, 0, CStat::E_NB_COUNTER * sizeof(unsigned long long))
   90 
   91 #define RESET_PD_COUNTERS(PT)                          \
   92 {                                                      \
   93   int i;                                               \
   94   for (i=CStat::CPT_PD_IncomingCallCreated;            \
   95        i<=CStat::CPT_PD_AutoAnswered;                  \
   96        i++)                                            \
   97     PT[i] = (unsigned long) 0;                         \
   98 }
   99 
  100 #define RESET_PL_COUNTERS(PT)                          \
  101 {                                                      \
  102   int i;                                               \
  103   for (i=CStat::CPT_PL_IncomingCallCreated;            \
  104        i<=CStat::CPT_PL_AutoAnswered;                  \
  105        i++)                                            \
  106     PT[i] = (unsigned long) 0;                         \
  107 }
  108 
  109 /*
  110   __________________________________________________________________________
  111 
  112   C L A S S    CS t a t
  113   __________________________________________________________________________
  114 */
  115 
  116 CStat* CStat::instance()
  117 {
  118   if ( M_instance == NULL ) M_instance = new CStat();
  119   return M_instance;
  120 }
  121 
  122 
  123 void CStat::close ()
  124 {
  125   int i;
  126 
  127   for (i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  128     if (M_ResponseTimeRepartition[i] != NULL) {
  129       delete [] M_ResponseTimeRepartition[i];
  130     }
  131   }
  132 
  133   if (M_CallLengthRepartition != NULL)
  134     delete [] M_CallLengthRepartition;
  135 
  136   if(M_outputStream != NULL)
  137     {
  138       M_outputStream->close();
  139       delete M_outputStream;
  140     }
  141 
  142   if(M_fileName != NULL)
  143     delete [] M_fileName;
  144 
  145   if(M_outputStreamRtt != NULL)
  146     {
  147       M_outputStreamRtt->close();
  148       delete M_outputStreamRtt;
  149     }
  150   if(M_fileNameRtt != NULL)
  151     delete [] M_fileNameRtt;
  152 
  153 
  154    if(M_dumpRespTime != NULL)
  155      delete [] M_dumpRespTime ;
  156 
  157 
  158   M_SizeOfResponseTimeRepartition = 0;
  159   M_SizeOfCallLengthRepartition   = 0;
  160   M_CallLengthRepartition         = NULL;
  161   M_fileName                      = NULL;
  162   M_outputStream                  = NULL;
  163 
  164   M_outputStreamRtt               = NULL;
  165   M_fileNameRtt                   = NULL;
  166   M_dumpRespTime                  = NULL;
  167 
  168   for (i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  169     M_ResponseTimeRepartition[i]  = NULL;
  170   }
  171 
  172   // On last position
  173   if (M_instance != NULL)
  174     delete M_instance;
  175   M_instance                      = NULL;
  176 }
  177 
  178 
  179 int CStat::init ()
  180 {
  181   // reset of all counter
  182   RESET_COUNTERS(M_counters);
  183   GET_TIME (&M_startTime);
  184   memcpy   (&M_pdStartTime, &M_startTime, sizeof (struct timeval));
  185   memcpy   (&M_plStartTime, &M_startTime, sizeof (struct timeval));
  186   M_outputStream = NULL;
  187   M_headerAlreadyDisplayed = false;
  188 
  189   M_outputStreamRtt = NULL;
  190   M_headerAlreadyDisplayedRtt = false;
  191 
  192   return(1);
  193 }
  194 
  195 
  196 int CStat::isWellFormed(char * P_listeStr,
  197                         int * nombre)
  198 {
  199   char * ptr = P_listeStr;
  200   int sizeOf;
  201   bool isANumber;
  202 
  203   (*nombre) = 0;
  204   sizeOf = strlen(P_listeStr);
  205   // getting the number
  206   if(sizeOf > 0)
  207     {
  208       // is the string well formed ? [0-9] [,]
  209       isANumber = false;
  210       for(int i=0; i<=sizeOf; i++)
  211         {
  212           switch(ptr[i])
  213             {
  214             case ',':
  215               if(isANumber == false)
  216                 {
  217                   return(0);
  218                 }
  219               else
  220                 {
  221                   (*nombre)++;
  222                 }
  223               isANumber = false;
  224               break;
  225             case '0':
  226             case '1':
  227             case '2':
  228             case '3':
  229             case '4':
  230             case '5':
  231             case '6':
  232             case '7':
  233             case '8':
  234             case '9':
  235               isANumber = true;
  236               break;
  237             case '\t':
  238             case ' ' :
  239               break;
  240             case '\0':
  241               if(isANumber == false)
  242                 {
  243                   return(0);
  244                 }
  245               else
  246                 {
  247                   (*nombre)++;
  248                 }
  249               break;
  250             default:
  251               return(0);
  252             }
  253         } // enf for
  254     }
  255   return(1);
  256 }
  257 
  258 
  259 int CStat::createIntegerTable(char * P_listeStr,
  260                               unsigned int ** listeInteger,
  261                               int * sizeOfList)
  262 {
  263   int nb=0;
  264   char * ptr = P_listeStr;
  265   char * ptr_prev = P_listeStr;
  266   unsigned int current_int;
  267 
  268   if(isWellFormed(P_listeStr, sizeOfList) == 1)
  269     {
  270       (*listeInteger) = new unsigned int[(*sizeOfList)];
  271       while((*ptr) != ('\0'))
  272         {
  273           if((*ptr) == ',')
  274             {
  275               sscanf(ptr_prev, "%u", &current_int);
  276               if (nb<(*sizeOfList))
  277                 (*listeInteger)[nb] = current_int;
  278               nb++;
  279               ptr_prev = ptr+1;
  280             }
  281           ptr++;
  282         }
  283       // on lit le dernier
  284       sscanf(ptr_prev, "%u", &current_int);
  285       if (nb<(*sizeOfList))
  286         (*listeInteger)[nb] = current_int;
  287       nb++;
  288       return(1);
  289     }
  290   return(0);
  291 }
  292 
  293 
  294 void CStat::setFileName(char * P_name, char * P_extension)
  295 {
  296   int sizeOf, sizeOfExtension;
  297 
  298   if(P_name != NULL)
  299     {
  300       // +6 for PID
  301       sizeOf = strlen(P_name) + 6;
  302       if(sizeOf > 0)
  303         {
  304           if(P_extension != NULL)
  305             {
  306               sizeOfExtension = strlen(P_extension);
  307               if(sizeOfExtension > 0)
  308                 {
  309                   if(M_fileName != NULL)
  310                     delete [] M_fileName;
  311                   sizeOf += sizeOfExtension;
  312                   M_fileName = new char[MAX_PATH];
  313                   sprintf(M_fileName, "%s_%d_", P_name, getpid());
  314                   strcat(M_fileName, P_extension);
  315                 }
  316               else
  317                 {
  318                   if(M_fileName != NULL)
  319                     delete [] M_fileName;
  320                   sizeOf += strlen(DEFAULT_EXTENSION);
  321                   M_fileName = new char[MAX_PATH];
  322                   sprintf(M_fileName, "%s_%d_", P_name, getpid());
  323                   strcat(M_fileName, DEFAULT_EXTENSION);
  324                 }
  325             }
  326           else
  327             {
  328               if(M_fileName != NULL)
  329                 delete [] M_fileName;
  330               sizeOf += strlen(DEFAULT_EXTENSION);
  331               M_fileName = new char[MAX_PATH];
  332               sprintf(M_fileName, "%s_%d_", P_name, getpid());
  333               strcat(M_fileName, DEFAULT_EXTENSION);
  334             }
  335         }
  336       else
  337         {
  338           cerr << "new file name length is null - "
  339                     << "keeping the default filename : "
  340                     << DEFAULT_FILE_NAME << endl;
  341         }
  342     }
  343   else
  344     {
  345       cerr << "new file name is NULL ! - keeping the default filename : "
  346                 << DEFAULT_FILE_NAME << endl;
  347     }
  348 }
  349 
  350 
  351 void CStat::setFileName(char * P_name)
  352 {
  353   int sizeOf;
  354 
  355   if(P_name != NULL)
  356     {
  357       sizeOf = strlen(P_name);
  358       if(sizeOf > 0)
  359         {
  360           if(M_fileName != NULL)
  361             delete [] M_fileName;
  362           M_fileName = new char[sizeOf+1];
  363           strcpy(M_fileName, P_name);
  364         }
  365       else
  366         {
  367           cerr << "new file name length is null - "
  368             "keeping the default filename : "
  369                     << DEFAULT_FILE_NAME << endl;
  370         }
  371     }
  372   else
  373     {
  374       cerr << "new file name is NULL ! - keeping the default filename : "
  375                 << DEFAULT_FILE_NAME << endl;
  376     }
  377 }
  378 
  379 
  380 void CStat::initRtt(char * P_name, char * P_extension,
  381                     unsigned long P_report_freq_dumpRtt) {
  382   int sizeOf, sizeOfExtension;
  383 
  384   if(P_name != NULL) {
  385     sizeOf = strlen(P_name) ;
  386     if(sizeOf > 0) {
  387       //  4 for '_rtt' and 6 for pid
  388       sizeOf += 10 ;
  389       sizeOfExtension = strlen(P_extension);
  390       if(M_fileNameRtt != NULL)
  391       delete [] M_fileNameRtt;
  392       sizeOf += sizeOfExtension;
  393       M_fileNameRtt = new char[sizeOf+1];
  394       sprintf (M_fileNameRtt, "%s_%d_rtt%s", P_name, getpid(),P_extension);
  395     } else {
  396       cerr << "new file name length is null - "
  397           << "keeping the default filename : "
  398           << DEFAULT_FILE_NAME << endl;
  399     }
  400   } else {
  401     cerr << "new file name is NULL ! - keeping the default filename : "
  402         << DEFAULT_FILE_NAME << endl;
  403   }
  404 
  405   // initiate the table dump response time
  406   M_report_freq_dumpRtt = P_report_freq_dumpRtt ;
  407 
  408   M_dumpRespTime = new T_value_rtt [P_report_freq_dumpRtt] ;
  409 
  410   if ( M_dumpRespTime == NULL ) {
  411     cerr << "Memory allocation failure" << endl;
  412     exit(EXIT_FATAL_ERROR);
  413   }
  414 
  415   for (unsigned L_i = 0 ; L_i < P_report_freq_dumpRtt; L_i ++) {
  416     M_dumpRespTime[L_i].date = 0.0;
  417     M_dumpRespTime[L_i].rtd_no = 0;
  418     M_dumpRespTime[L_i].rtt = 0.0;
  419   }
  420 }
  421 
  422 void CStat::setRepartitionCallLength(char * P_listeStr)
  423 {
  424   unsigned int * listeInteger;
  425   int sizeOfListe;
  426 
  427   if(createIntegerTable(P_listeStr, &listeInteger, &sizeOfListe) == 1) {
  428     initRepartition(listeInteger,
  429                     sizeOfListe,
  430                     &M_CallLengthRepartition,
  431                     &M_SizeOfCallLengthRepartition);
  432   } else {
  433     ERROR_P1("Could not create table for call length repartition '%s'\n", P_listeStr);
  434   }
  435   delete [] listeInteger;
  436   listeInteger = NULL;
  437 }
  438 
  439 void CStat::setRepartitionResponseTime (char * P_listeStr)
  440 {
  441   unsigned int * listeInteger;
  442   int sizeOfListe;
  443   int i;
  444 
  445   for (i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  446     if(createIntegerTable(P_listeStr, &listeInteger, &sizeOfListe) == 1) {
  447       initRepartition(listeInteger,
  448     sizeOfListe,
  449     &M_ResponseTimeRepartition[i],
  450     &M_SizeOfResponseTimeRepartition);
  451     } else {
  452       ERROR_P1("Could not create table for response time repartition '%s'\n", P_listeStr);
  453     }
  454   }
  455   delete [] listeInteger;
  456   listeInteger = NULL;
  457 }
  458 
  459 
  460 void CStat::setRepartitionCallLength(unsigned int* repartition,
  461                                      int nombre)
  462 {
  463   initRepartition(repartition,
  464                   nombre,
  465                   &M_CallLengthRepartition,
  466                   &M_SizeOfCallLengthRepartition);
  467 }
  468 
  469 void CStat::setRepartitionResponseTime(unsigned int* repartition,
  470                                        int nombre)
  471 {
  472   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  473     initRepartition(repartition,
  474                     nombre,
  475                     &M_ResponseTimeRepartition[i],
  476                     &M_SizeOfResponseTimeRepartition);
  477   }
  478 }
  479 
  480 
  481 void CStat::initRepartition(unsigned int* repartition,
  482                             int nombre,
  483                             T_dynamicalRepartition ** tabRepartition,
  484                             int* tabNb)
  485 {
  486   bool sortDone;
  487   int i;
  488   unsigned int swap;
  489 
  490   if((nombre <= 0) || (repartition == NULL) )
  491     {
  492       (*tabNb)          = 0;
  493       (*tabRepartition) = NULL;
  494       return;
  495     }
  496 
  497   (*tabNb)          = nombre + 1;
  498   (*tabRepartition) = new T_dynamicalRepartition[(*tabNb)];
  499 
  500   // copying the repartition table in the local table
  501   for(i=0; i<nombre; i++)
  502     {
  503       (*tabRepartition)[i].borderMax      = repartition[i];
  504       (*tabRepartition)[i].nbInThisBorder = 0;
  505     }
  506 
  507   // sorting the repartition table
  508   sortDone = false;
  509   while(!sortDone)
  510     {
  511       sortDone = true;
  512       for(i=0; i<(nombre-1); i++)
  513         {
  514           if((*tabRepartition)[i].borderMax > (*tabRepartition)[i+1].borderMax)
  515             {
  516               // swapping this two value and setting sortDone to false
  517               swap = (*tabRepartition)[i].borderMax;
  518               (*tabRepartition)[i].borderMax =
  519                 (*tabRepartition)[i+1].borderMax;
  520               (*tabRepartition)[i+1].borderMax = swap;
  521               sortDone = false;
  522             }
  523         }
  524     }
  525   // setting the range for max <= value < infinity
  526   (*tabRepartition)[nombre].borderMax =
  527     (*tabRepartition)[nombre-1].borderMax;
  528   (*tabRepartition)[nombre].nbInThisBorder = 0;
  529 }
  530 
  531 
  532 int CStat::computeStat (E_Action P_action)
  533 {
  534   switch (P_action)
  535     {
  536     case E_CREATE_OUTGOING_CALL :
  537       M_counters [CPT_C_OutgoingCallCreated]++;
  538       M_counters [CPT_PD_OutgoingCallCreated]++;
  539       M_counters [CPT_PL_OutgoingCallCreated]++;
  540       M_counters [CPT_C_CurrentCall]++;
  541       break;
  542 
  543     case E_CREATE_INCOMING_CALL :
  544       M_counters [CPT_C_IncomingCallCreated]++;
  545       M_counters [CPT_PD_IncomingCallCreated]++;
  546       M_counters [CPT_PL_IncomingCallCreated]++;
  547       M_counters [CPT_C_CurrentCall]++;
  548       break;
  549 
  550     case E_CALL_FAILED :
  551       M_counters [CPT_C_FailedCall]++;
  552       M_counters [CPT_PD_FailedCall]++;
  553       M_counters [CPT_PL_FailedCall]++;
  554       M_counters [CPT_C_CurrentCall]--;
  555       break;
  556 
  557     case E_CALL_SUCCESSFULLY_ENDED :
  558       M_counters [CPT_C_SuccessfulCall]++;
  559       M_counters [CPT_PD_SuccessfulCall]++;
  560       M_counters [CPT_PL_SuccessfulCall]++;
  561       M_counters [CPT_C_CurrentCall]--;
  562       break;
  563 
  564     case E_FAILED_CANNOT_SEND_MSG :
  565       M_counters [CPT_C_FailedCallCannotSendMessage]++;
  566       M_counters [CPT_PD_FailedCallCannotSendMessage]++;
  567       M_counters [CPT_PL_FailedCallCannotSendMessage]++;
  568       break;
  569 
  570     case E_FAILED_MAX_UDP_RETRANS :
  571       M_counters [CPT_C_FailedCallMaxUdpRetrans]++;
  572       M_counters [CPT_PD_FailedCallMaxUdpRetrans]++;
  573       M_counters [CPT_PL_FailedCallMaxUdpRetrans]++;
  574       break;
  575 
  576     case E_FAILED_UNEXPECTED_MSG :
  577       M_counters [CPT_C_FailedCallUnexpectedMessage]++;
  578       M_counters [CPT_PD_FailedCallUnexpectedMessage]++;
  579       M_counters [CPT_PL_FailedCallUnexpectedMessage]++;
  580       break;
  581 
  582     case E_FAILED_CALL_REJECTED :
  583       M_counters [CPT_C_FailedCallCallRejected]++;
  584       M_counters [CPT_PD_FailedCallCallRejected]++;
  585       M_counters [CPT_PL_FailedCallCallRejected]++;
  586       break;
  587 
  588     case E_FAILED_CMD_NOT_SENT :
  589       M_counters [CPT_C_FailedCallCmdNotSent]++;
  590       M_counters [CPT_PD_FailedCallCmdNotSent]++;
  591       M_counters [CPT_PL_FailedCallCmdNotSent]++;
  592       break;
  593 
  594     case E_FAILED_REGEXP_DOESNT_MATCH :
  595       M_counters [CPT_C_FailedCallRegexpDoesntMatch]++;
  596       M_counters [CPT_PD_FailedCallRegexpDoesntMatch]++;
  597       M_counters [CPT_PL_FailedCallRegexpDoesntMatch]++;
  598       break;
  599 
  600     case E_FAILED_REGEXP_HDR_NOT_FOUND :
  601       M_counters [CPT_C_FailedCallRegexpHdrNotFound]++;
  602       M_counters [CPT_PD_FailedCallRegexpHdrNotFound]++;
  603       M_counters [CPT_PL_FailedCallRegexpHdrNotFound]++;
  604       break;
  605 
  606     case E_FAILED_OUTBOUND_CONGESTION :
  607       M_counters [CPT_C_FailedOutboundCongestion]++;
  608       M_counters [CPT_PD_FailedOutboundCongestion]++;
  609       M_counters [CPT_PL_FailedOutboundCongestion]++;
  610       break;
  611 
  612     case E_FAILED_TIMEOUT_ON_RECV :
  613       M_counters [CPT_C_FailedTimeoutOnRecv]++;
  614       M_counters [CPT_PD_FailedTimeoutOnRecv]++;
  615       M_counters [CPT_PL_FailedTimeoutOnRecv]++;
  616       break;
  617 
  618     case E_FAILED_TIMEOUT_ON_SEND :
  619       M_counters [CPT_C_FailedTimeoutOnSend]++;
  620       M_counters [CPT_PD_FailedTimeoutOnSend]++;
  621       M_counters [CPT_PL_FailedTimeoutOnSend]++;
  622       break;
  623 
  624     case E_OUT_OF_CALL_MSGS :
  625       M_counters [CPT_C_OutOfCallMsgs]++;
  626       M_counters [CPT_PD_OutOfCallMsgs]++;
  627       M_counters [CPT_PL_OutOfCallMsgs]++;
  628       break;
  629 
  630     case E_RETRANSMISSION :
  631       M_counters [CPT_C_Retransmissions]++;
  632       M_counters [CPT_PD_Retransmissions]++;
  633       M_counters [CPT_PL_Retransmissions]++;
  634       break;
  635 
  636 
  637     case E_AUTO_ANSWERED :
  638       // Let's count the automatic answered calls
  639       M_counters [CPT_C_AutoAnswered]++;
  640       M_counters [CPT_PD_AutoAnswered]++;
  641       M_counters [CPT_PL_AutoAnswered]++;
  642       break;
  643 
  644     case E_RESET_PD_COUNTERS :
  645       //DEBUG (C_Debug::E_LEVEL_4, "ENTER CASE", "%s",
  646       //       "CStat::computeStat : RESET_PD_COUNTERS");
  647       RESET_PD_COUNTERS (M_counters);
  648       GET_TIME (&M_pdStartTime);
  649       break;
  650 
  651     case E_RESET_PL_COUNTERS :
  652       //DEBUG (C_Debug::E_LEVEL_4, "ENTER CASE", "%s",
  653       //       "C_Stat::computeStat : RESET_PL_COUNTERS");
  654       RESET_PL_COUNTERS (M_counters);
  655       GET_TIME (&M_plStartTime);
  656       break;
  657 
  658     default :
  659       ERROR_P1("CStat::ComputeStat() - Unrecognized Action %d\n", P_action);
  660       return (-1);
  661     } /* end switch */
  662   return (0);
  663 }
  664 
  665 void CStat::computeRtt (unsigned long long P_start_time, unsigned long long P_stop_time, int which) {
  666   M_dumpRespTime[M_counterDumpRespTime].date = (double)P_stop_time / (double)1000;
  667   M_dumpRespTime[M_counterDumpRespTime].rtd_no = which;
  668   M_dumpRespTime[M_counterDumpRespTime].rtt =
  669     ((double)(P_stop_time - P_start_time)) / (double)1000;
  670   M_counterDumpRespTime++ ;
  671 
  672   if (M_counterDumpRespTime > (M_report_freq_dumpRtt - 1)) {
  673     dumpDataRtt () ;
  674   }
  675 }
  676 
  677 unsigned long long CStat::get_current_counter_call (){
  678   return M_counters[CPT_C_CurrentCall];
  679 }
  680 
  681 unsigned long long CStat::GetStat (E_CounterName P_counter)
  682 {
  683   return M_counters [P_counter];
  684 }
  685 
  686 /* Use the short form standard deviation formula given the sum of the squares
  687  * and the sum. */
  688 double CStat::computeStdev(E_CounterName P_SumCounter,
  689        E_CounterName P_NbOfCallUsed,
  690        E_CounterName P_Squares) {
  691   if (M_counters[P_NbOfCallUsed] == 0)
  692     return 0.0;
  693 
  694   double numerator = ((double)(M_counters[P_NbOfCallUsed]) * (double)(M_counters[P_Squares])) - ((double)(M_counters[P_SumCounter] * M_counters[P_SumCounter]));
  695   double denominator = (double)(M_counters[P_NbOfCallUsed]) * (((double)(M_counters[P_NbOfCallUsed])) - 1.0);
  696 
  697   return sqrt(numerator/denominator);
  698 }
  699 
  700 double CStat::computeMean(E_CounterName P_SumCounter,
  701        E_CounterName P_NbOfCallUsed) {
  702   if (M_counters[P_NbOfCallUsed] == 0)
  703     return 0.0;
  704   return ((double)(M_counters[P_SumCounter]) / (double)(M_counters[P_NbOfCallUsed]));
  705 }
  706 
  707 void CStat::updateAverageCounter(E_CounterName P_SumCounter,
  708                                  E_CounterName P_NbOfCallUsed,
  709                                  E_CounterName P_Squares,
  710                                  unsigned long P_value)
  711 {
  712   if (M_counters [P_NbOfCallUsed] <= 0)
  713     {
  714       M_counters [P_NbOfCallUsed] ++;
  715       M_counters [P_SumCounter] = P_value;
  716       M_counters [P_Squares] = (P_value * P_value);
  717     }
  718   else
  719     {
  720       M_counters [P_SumCounter] += P_value;
  721       M_counters [P_Squares] += (P_value * P_value);
  722       M_counters [P_NbOfCallUsed] ++;
  723     }
  724 }
  725 
  726 int CStat::computeStat (E_Action P_action,
  727                         unsigned long P_value) {
  728   return computeStat(P_action, P_value, 0);
  729 }
  730 
  731 int CStat::computeStat (E_Action P_action,
  732                         unsigned long P_value,
  733       int which)
  734 {
  735   switch (P_action)
  736     {
  737     case E_ADD_CALL_DURATION :
  738       // Updating Cumulative Counter
  739       updateAverageCounter(CPT_C_AverageCallLength_Sum,
  740                            CPT_C_NbOfCallUsedForAverageCallLength,
  741          CPT_C_AverageCallLength_Squares, P_value);
  742       updateRepartition(M_CallLengthRepartition,
  743                         M_SizeOfCallLengthRepartition, P_value);
  744       // Updating Periodical Diplayed counter
  745       updateAverageCounter(CPT_PD_AverageCallLength_Sum,
  746                            CPT_PD_NbOfCallUsedForAverageCallLength,
  747          CPT_PD_AverageCallLength_Squares, P_value);
  748       // Updating Periodical Logging counter
  749       updateAverageCounter(CPT_PL_AverageCallLength_Sum,
  750                            CPT_PL_NbOfCallUsedForAverageCallLength,
  751          CPT_PL_AverageCallLength_Squares, P_value);
  752       break;
  753 
  754 
  755     case E_ADD_GENERIC_COUNTER :
  756       M_counters [CPT_C_Generic + which] += P_value;
  757       M_counters [CPT_PD_Generic + which] += P_value;
  758       M_counters [CPT_PL_Generic + which] += P_value;
  759       break;
  760 
  761     case E_ADD_RESPONSE_TIME_DURATION :
  762       // Updating Cumulative Counter
  763       updateAverageCounter((E_CounterName)(CPT_C_AverageResponseTime_Sum + which),
  764                            (E_CounterName)(CPT_C_NbOfCallUsedForAverageResponseTime + which),
  765                            (E_CounterName)(CPT_C_AverageResponseTime_Squares + which), P_value);
  766       updateRepartition(M_ResponseTimeRepartition[which],
  767                         M_SizeOfResponseTimeRepartition, P_value);
  768       // Updating Periodical Diplayed counter
  769       updateAverageCounter((E_CounterName)(CPT_PD_AverageResponseTime_Sum + which),
  770                            (E_CounterName)(CPT_PD_NbOfCallUsedForAverageResponseTime + which),
  771                            (E_CounterName)(CPT_PD_AverageResponseTime_Squares + which), P_value);
  772       // Updating Periodical Logging counter
  773       updateAverageCounter((E_CounterName)(CPT_PL_AverageResponseTime_Sum + which),
  774                            (E_CounterName)(CPT_PL_NbOfCallUsedForAverageResponseTime + which),
  775                            (E_CounterName)(CPT_PL_AverageResponseTime_Squares + which), P_value);
  776       break;
  777 
  778     default :
  779       ERROR_P1("CStat::ComputeStat() - Unrecognized Action %d\n", P_action);
  780       return (-1);
  781     } /* end switch */
  782   return (0);
  783 }
  784 
  785 
  786 void CStat::updateRepartition(T_dynamicalRepartition* P_tabReport,
  787                               int P_sizeOfTab,
  788                               unsigned long P_value)
  789 {
  790   bool found;
  791   int i;
  792 
  793   if(P_tabReport != NULL)
  794     {
  795       i = P_sizeOfTab-2;
  796       found = false;
  797       while((found == false) && (i>=1))
  798         {
  799           if( (P_value < P_tabReport[i].borderMax) &&
  800               (P_tabReport[i-1].borderMax <= P_value) )
  801             {
  802               found = true;
  803               P_tabReport[i].nbInThisBorder ++;
  804             }
  805           i--;
  806         }
  807 
  808       if(!found)
  809         {
  810           if(P_value < P_tabReport[0].borderMax)
  811             {
  812               P_tabReport[0].nbInThisBorder ++;
  813             }
  814           else if(P_value >= P_tabReport[P_sizeOfTab-1].borderMax)
  815             {
  816               P_tabReport[P_sizeOfTab-1].nbInThisBorder ++;
  817             }
  818           else
  819             {
  820               // ERROR !!!!
  821               printf("\n ERROR - Unable to sort this Value in "
  822                      "the repartition table! %lu \n", P_value);
  823             }
  824         }
  825     }
  826 }
  827 
  828 
  829 CStat::CStat ()
  830 {
  831   size_t L_size = 0;
  832   L_size += strlen(DEFAULT_FILE_NAME) ;
  833   L_size += strlen(DEFAULT_EXTENSION) ;
  834   L_size += 1 ;
  835   M_fileName = new char[L_size];
  836   strcpy(M_fileName, DEFAULT_FILE_NAME);
  837   strcat(M_fileName, DEFAULT_EXTENSION);
  838   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  839     M_ResponseTimeRepartition[i] = NULL;
  840   }
  841   M_CallLengthRepartition   = NULL;
  842   M_SizeOfResponseTimeRepartition = 0;
  843   M_SizeOfCallLengthRepartition   = 0;
  844   M_fileNameRtt = NULL;
  845   M_time_ref = 0.0                   ;
  846   M_dumpRespTime = NULL              ;
  847   M_counterDumpRespTime = 0          ;
  848   M_dumpRespTime = NULL;
  849   M_fileNameRtt  = NULL;
  850 
  851   init();
  852 }
  853 
  854 
  855 CStat::~CStat ()
  856 {
  857   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
  858     if (M_ResponseTimeRepartition[i] == NULL)
  859   continue;
  860     delete M_ResponseTimeRepartition[i];
  861   }
  862   if (M_CallLengthRepartition != NULL)
  863     delete M_CallLengthRepartition;
  864 }
  865 
  866 char* CStat::sRepartitionHeader(T_dynamicalRepartition * tabRepartition,
  867                                 int sizeOfTab,
  868                                 char * P_repartitionName)
  869 {
  870   static char  repartitionHeader[MAX_REPARTITION_HEADER_LENGTH];
  871   char buffer[MAX_CHAR_BUFFER_SIZE];
  872 
  873   if(tabRepartition != NULL)
  874     {
  875       sprintf(repartitionHeader, "%s%s", P_repartitionName, stat_delimiter);
  876       for(int i=0; i<(sizeOfTab-1); i++)
  877         {
  878           sprintf(buffer, "<%d%s", tabRepartition[i].borderMax, stat_delimiter);
  879           strcat(repartitionHeader, buffer);
  880         }
  881       sprintf(buffer, ">=%d%s", tabRepartition[sizeOfTab-1].borderMax, stat_delimiter);
  882       strcat(repartitionHeader, buffer);
  883     }
  884   else
  885     {
  886       repartitionHeader[0] = '\0';
  887     }
  888 
  889   return(repartitionHeader);
  890 }
  891 
  892 char* CStat::sRepartitionInfo(T_dynamicalRepartition * tabRepartition,
  893                               int sizeOfTab)
  894 {
  895   static char repartitionInfo[MAX_REPARTITION_INFO_LENGTH];
  896   char buffer[MAX_CHAR_BUFFER_SIZE];
  897 
  898   if(tabRepartition != NULL)
  899     {
  900       // if a repartition is present, this field match the repartition name
  901       sprintf(repartitionInfo, stat_delimiter);
  902       for(int i=0; i<(sizeOfTab-1); i++)
  903         {
  904           sprintf(buffer, "%lu%s", tabRepartition[i].nbInThisBorder, stat_delimiter);
  905           strcat(repartitionInfo, buffer);
  906         }
  907       sprintf(buffer, "%lu%s", tabRepartition[sizeOfTab-1].nbInThisBorder, stat_delimiter);
  908       strcat(repartitionInfo, buffer);
  909     }
  910   else
  911     {
  912       repartitionInfo[0] = '\0';
  913     }
  914 
  915   return(repartitionInfo);
  916 }
  917 
  918 
  919 void CStat::displayRepartition(FILE *f,
  920                                T_dynamicalRepartition * tabRepartition,
  921                                int sizeOfTab)
  922 {
  923   if(tabRepartition != NULL) {
  924     for(int i=0; i<(sizeOfTab-1); i++) {
  925       if(i==0) {
  926         DISPLAY_REPART(0, tabRepartition[i].borderMax,
  927                         tabRepartition[i].nbInThisBorder);
  928       } else {
  929         DISPLAY_REPART(tabRepartition[i-1].borderMax,
  930                        tabRepartition[i].borderMax,
  931                        tabRepartition[i].nbInThisBorder);
  932       }
  933     }
  934     DISPLAY_LAST_REPART (tabRepartition[sizeOfTab-1].borderMax,
  935                          tabRepartition[sizeOfTab-1].nbInThisBorder);
  936   } else {
  937     DISPLAY_INFO ("  <No repartion defined>");
  938   }
  939 }
  940 
  941 void CStat::displayData (FILE *f)
  942 {
  943   long   localElapsedTime, globalElapsedTime ;
  944   struct timeval currentTime;
  945   float  averageCallRate;
  946   float  realInstantCallRate;
  947   unsigned long numberOfCall;
  948 
  949   GET_TIME (&currentTime);
  950   // computing the real call rate
  951   globalElapsedTime   = computeDiffTimeInMs (&currentTime, &M_startTime);
  952   localElapsedTime    = computeDiffTimeInMs (&currentTime, &M_pdStartTime);
  953 
  954   // the call rate is for all the call : incoming and outgoing
  955   numberOfCall        = M_counters[CPT_C_IncomingCallCreated] +
  956     M_counters[CPT_C_OutgoingCallCreated];
  957   averageCallRate     = (globalElapsedTime > 0 ?
  958                          1000*(float)numberOfCall/(float)globalElapsedTime
  959                          : 0.0);
  960   numberOfCall        = (M_counters[CPT_PD_IncomingCallCreated] +
  961                          M_counters[CPT_PD_OutgoingCallCreated]);
  962   realInstantCallRate = (localElapsedTime  > 0 ?
  963                          1000*(float)numberOfCall / (float)localElapsedTime :
  964                          0.0);
  965 
  966   // display info
  967   DISPLAY_DLINE ();
  968   // build and display header info
  969   DISPLAY_TXT ("Start Time  ", formatTime(&M_startTime));
  970   DISPLAY_TXT ("Last Reset Time", formatTime(&M_pdStartTime));
  971   DISPLAY_TXT ("Current Time", formatTime(&currentTime));
  972 
  973   // printing the header in the middle
  974   DISPLAY_CROSS_LINE();
  975   DISPLAY_HEADER();
  976   DISPLAY_CROSS_LINE();
  977 
  978   DISPLAY_TXT_COL ("Elapsed Time",
  979                    msToHHMMSSmmm(localElapsedTime),
  980                    msToHHMMSSmmm(globalElapsedTime));
  981 
  982   DISPLAY_VAL_RATEF_COL ("Call Rate",
  983                          realInstantCallRate,
  984                          averageCallRate);
  985   DISPLAY_CROSS_LINE ();
  986 
  987   DISPLAY_2VAL  ("Incoming call created",
  988                  M_counters[CPT_PD_IncomingCallCreated],
  989                  M_counters[CPT_C_IncomingCallCreated]);
  990   DISPLAY_2VAL  ("OutGoing call created",
  991                  M_counters[CPT_PD_OutgoingCallCreated],
  992                  M_counters[CPT_C_OutgoingCallCreated]);
  993   DISPLAY_CUMUL ("Total Call created", M_counters[CPT_C_IncomingCallCreated] +
  994                  M_counters[CPT_C_OutgoingCallCreated]);
  995   DISPLAY_PERIO ("Current Call",       M_counters[CPT_C_CurrentCall]);
  996 
  997   bool first = true;
  998   for (int i = 0; i < MAX_COUNTER; i++) {
  999     char s[20];
 1000 
 1001     if (M_counters[CPT_C_Generic + i] == 0) {
 1002       continue;
 1003     }
 1004 
 1005     if (first) {
 1006       DISPLAY_CROSS_LINE ();
 1007       first = false;
 1008     }
 1009 
 1010     sprintf(s, "Generic counter %d", i + 1);
 1011 
 1012     DISPLAY_2VAL(s, M_counters[CPT_PD_Generic + i], M_counters[CPT_C_Generic + i]);
 1013   }
 1014 
 1015   DISPLAY_CROSS_LINE ();
 1016   DISPLAY_2VAL  ("Successful call",
 1017                  M_counters[CPT_PD_SuccessfulCall],
 1018                  M_counters[CPT_C_SuccessfulCall]);
 1019   DISPLAY_2VAL  ("Failed call",
 1020                  M_counters[CPT_PD_FailedCall],
 1021                  M_counters[CPT_C_FailedCall]);
 1022   // DISPLAY_2VAL  ("Unexpected msg",
 1023   //                 M_counters[CPT_PD_UnexpectedMessage],
 1024   //                 M_counters[CPT_C_UnexpectedMessage]);
 1025 
 1026   DISPLAY_CROSS_LINE ();
 1027   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1028     char s[15];
 1029 
 1030     if (!rtd_stopped[i]) {
 1031       continue;
 1032     }
 1033 
 1034     sprintf(s, "Response Time %d", i + 1);
 1035     DISPLAY_TXT_COL (s,
 1036   msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_PD_AverageResponseTime_Sum + i), (E_CounterName)(CPT_PD_NbOfCallUsedForAverageResponseTime + i)) ),
 1037   msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_C_AverageResponseTime_Sum + i), (E_CounterName)(CPT_C_NbOfCallUsedForAverageResponseTime + i)) ) );
 1038   }
 1039   DISPLAY_TXT_COL ("Call Length",
 1040                    msToHHMMSSmmm( (unsigned long)computeMean(CPT_PD_AverageCallLength_Sum, CPT_PD_NbOfCallUsedForAverageCallLength)),
 1041                    msToHHMMSSmmm( (unsigned long)computeMean(CPT_C_AverageCallLength_Sum, CPT_C_NbOfCallUsedForAverageCallLength) ));
 1042   DISPLAY_CROSS_LINE ();
 1043 
 1044   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1045     char s[50];
 1046 
 1047     if (!rtd_stopped[i]) {
 1048       continue;
 1049     }
 1050 
 1051     sprintf(s, "Average Response Time Repartition, %d", i + 1);
 1052     DISPLAY_INFO(s);
 1053     displayRepartition(f, M_ResponseTimeRepartition[i], M_SizeOfResponseTimeRepartition);
 1054   }
 1055   DISPLAY_INFO("Average Call Length Repartition");
 1056   displayRepartition(f, M_CallLengthRepartition, M_SizeOfCallLengthRepartition);
 1057 
 1058   //  DISPLAY_VAL ("NbCall Average RT(P)",
 1059   //                 M_counters[CPT_PD_NbOfCallUsedForAverageResponseTime]);
 1060   //  DISPLAY_VAL ("NbCall Average RT",
 1061   //                 M_counters[CPT_C_NbOfCallUsedForAverageResponseTime]);
 1062   //  DISPLAY_VAL ("NbCall Average CL",
 1063   //                 M_counters[CPT_C_NbOfCallUsedForAverageCallLength]);
 1064   //  DISPLAY_VAL ("NbCall Average CL(P)",
 1065   //                 M_counters[CPT_PD_NbOfCallUsedForAverageCallLength]);
 1066   DISPLAY_DLINE ();
 1067 } /* end of displayData () */
 1068 
 1069 
 1070 void CStat::displayStat (FILE *f)
 1071 {
 1072   long   localElapsedTime, globalElapsedTime ;
 1073   struct timeval currentTime;
 1074   float  averageCallRate;
 1075   float  realInstantCallRate;
 1076   unsigned long numberOfCall;
 1077 
 1078   GET_TIME (&currentTime);
 1079   // computing the real call rate
 1080   globalElapsedTime   = computeDiffTimeInMs (&currentTime, &M_startTime);
 1081   localElapsedTime    = computeDiffTimeInMs (&currentTime, &M_pdStartTime);
 1082   // the call rate is for all the call : incoming and outgoing
 1083   numberOfCall        = (M_counters[CPT_C_IncomingCallCreated] +
 1084                          M_counters[CPT_C_OutgoingCallCreated]);
 1085   averageCallRate     = (globalElapsedTime > 0 ?
 1086                          1000*(float)numberOfCall/(float)globalElapsedTime :
 1087                          0.0);
 1088   numberOfCall        = (M_counters[CPT_PD_IncomingCallCreated] +
 1089                          M_counters[CPT_PD_OutgoingCallCreated]);
 1090   realInstantCallRate = (localElapsedTime  > 0 ?
 1091                          1000*(float)numberOfCall / (float)localElapsedTime :
 1092                          0.0);
 1093 
 1094   // build and display header info
 1095   DISPLAY_TXT ("Start Time  ", formatTime(&M_startTime));
 1096   DISPLAY_TXT ("Last Reset Time", formatTime(&M_pdStartTime));
 1097   DISPLAY_TXT ("Current Time", formatTime(&currentTime));
 1098 
 1099   // printing the header in the middle
 1100   DISPLAY_CROSS_LINE();
 1101   DISPLAY_HEADER();
 1102   DISPLAY_CROSS_LINE();
 1103 
 1104   DISPLAY_TXT_COL ("Elapsed Time",
 1105                    msToHHMMSSmmm(localElapsedTime),
 1106                    msToHHMMSSmmm(globalElapsedTime));
 1107 
 1108   DISPLAY_VAL_RATEF_COL ("Call Rate",  realInstantCallRate, averageCallRate);
 1109   DISPLAY_CROSS_LINE ();
 1110 
 1111   DISPLAY_2VAL  ("Incoming call created",
 1112                  M_counters[CPT_PD_IncomingCallCreated],
 1113                  M_counters[CPT_C_IncomingCallCreated]);
 1114   DISPLAY_2VAL  ("OutGoing call created",
 1115                  M_counters[CPT_PD_OutgoingCallCreated],
 1116                  M_counters[CPT_C_OutgoingCallCreated]);
 1117   DISPLAY_CUMUL ("Total Call created", M_counters[CPT_C_IncomingCallCreated] +
 1118                  M_counters[CPT_C_OutgoingCallCreated]);
 1119   DISPLAY_PERIO ("Current Call",
 1120                  M_counters[CPT_C_CurrentCall]);
 1121 
 1122   bool first = true;
 1123   for (int i = 0; i < MAX_COUNTER; i++) {
 1124     char s[20];
 1125 
 1126     if (M_counters[CPT_C_Generic + i] == 0) {
 1127       continue;
 1128     }
 1129 
 1130     if (first) {
 1131       DISPLAY_CROSS_LINE ();
 1132       first = false;
 1133     }
 1134 
 1135     sprintf(s, "Generic counter %d", i + 1);
 1136 
 1137     DISPLAY_2VAL(s, M_counters[CPT_PD_Generic + i], M_counters[CPT_C_Generic + i]);
 1138   }
 1139 
 1140   DISPLAY_CROSS_LINE ();
 1141   DISPLAY_2VAL  ("Successful call",
 1142                  M_counters[CPT_PD_SuccessfulCall],
 1143                  M_counters[CPT_C_SuccessfulCall]);
 1144   DISPLAY_2VAL  ("Failed call",
 1145                  M_counters[CPT_PD_FailedCall],
 1146                  M_counters[CPT_C_FailedCall]);
 1147   //DISPLAY_2VAL  ("Unexpected msg",
 1148   //               M_counters[CPT_PD_UnexpectedMessage],
 1149   //               M_counters[CPT_C_UnexpectedMessage]);
 1150 
 1151   DISPLAY_CROSS_LINE ();
 1152   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1153     char s[20];
 1154 
 1155     if (!rtd_stopped[i]) {
 1156       continue;
 1157     }
 1158 
 1159 
 1160     sprintf(s, "Response Time %d", i + 1);
 1161     DISPLAY_TXT_COL (s,
 1162   msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_PD_AverageResponseTime_Sum + i), (E_CounterName)(CPT_PD_NbOfCallUsedForAverageResponseTime + i)) ),
 1163   msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_C_AverageResponseTime_Sum + i), (E_CounterName)(CPT_C_NbOfCallUsedForAverageResponseTime + i))));
 1164   }
 1165   DISPLAY_TXT_COL ("Call Length",
 1166                    msToHHMMSSmmm( (unsigned long)computeMean(CPT_PD_AverageCallLength_Sum, CPT_PD_NbOfCallUsedForAverageCallLength ) ),
 1167                    msToHHMMSSmmm( (unsigned long)computeMean(CPT_C_AverageCallLength_Sum, CPT_C_NbOfCallUsedForAverageCallLength) ));
 1168 }
 1169 
 1170 void CStat::displayRepartition (FILE *f)
 1171 {
 1172   DISPLAY_INFO("Average Response Time Repartition");
 1173   displayRepartition(f,
 1174                      M_ResponseTimeRepartition[0],
 1175                      M_SizeOfResponseTimeRepartition);
 1176   DISPLAY_INFO("Average Call Length Repartition");
 1177   displayRepartition(f,
 1178                      M_CallLengthRepartition,
 1179                      M_SizeOfCallLengthRepartition);
 1180 }
 1181 
 1182 void CStat::displaySecondaryRepartition (FILE *f, int which)
 1183 {
 1184   DISPLAY_INFO("Average Response Time Repartition");
 1185   displayRepartition(f,
 1186                      M_ResponseTimeRepartition[which],
 1187                      M_SizeOfResponseTimeRepartition);
 1188 }
 1189 
 1190 
 1191 void CStat::dumpData ()
 1192 {
 1193   long   localElapsedTime, globalElapsedTime ;
 1194   struct timeval currentTime;
 1195   float  averageCallRate;
 1196   float  realInstantCallRate;
 1197   unsigned long numberOfCall;
 1198 
 1199   // computing the real call rate
 1200   GET_TIME (&currentTime);
 1201   globalElapsedTime   = computeDiffTimeInMs (&currentTime, &M_startTime);
 1202   localElapsedTime    = computeDiffTimeInMs (&currentTime, &M_plStartTime);
 1203 
 1204   // the call rate is for all the call : incoming and outgoing
 1205   numberOfCall        = (M_counters[CPT_C_IncomingCallCreated] +
 1206                          M_counters[CPT_C_OutgoingCallCreated]);
 1207   averageCallRate     = (globalElapsedTime > 0 ?
 1208                          1000*(float)numberOfCall/(float)globalElapsedTime :
 1209                          0.0);
 1210   numberOfCall        = (M_counters[CPT_PL_IncomingCallCreated] +
 1211                          M_counters[CPT_PL_OutgoingCallCreated]);
 1212   realInstantCallRate = (localElapsedTime  > 0 ?
 1213                          1000*(float)numberOfCall / (float)localElapsedTime :
 1214                          0.0);
 1215 
 1216   if(M_outputStream == NULL) {
 1217     // if the file is still not opened, we opened it now
 1218     M_outputStream = new ofstream(M_fileName);
 1219     M_headerAlreadyDisplayed = false;
 1220 
 1221     if(M_outputStream == NULL) {
 1222       cerr << "Unable to open stat file '" << M_fileName << "' !" << endl;
 1223       exit(EXIT_FATAL_ERROR);
 1224     }
 1225 
 1226 #ifndef __osf__
 1227     if(!M_outputStream->is_open())
 1228       {
 1229         cerr << "Unable to open stat file '" << M_fileName << "' !" << endl;
 1230         exit(EXIT_FATAL_ERROR);
 1231       }
 1232 #endif
 1233 
 1234   }
 1235 
 1236   if(M_headerAlreadyDisplayed == false) {
 1237     // header - it's dump in file only one time at the beginning of the file
 1238     (*M_outputStream) << "StartTime" << stat_delimiter
 1239                       << "LastResetTime" << stat_delimiter
 1240                       << "CurrentTime" << stat_delimiter
 1241                       << "ElapsedTime(P)" << stat_delimiter
 1242                       << "ElapsedTime(C)" << stat_delimiter
 1243                       << "CallRate(P)" << stat_delimiter
 1244                       << "CallRate(C)" << stat_delimiter
 1245                       << "IncomingCall(P)" << stat_delimiter
 1246                       << "IncomingCall(C)" << stat_delimiter
 1247                       << "OutgoingCall(P)" << stat_delimiter
 1248                       << "OutgoingCall(C)" << stat_delimiter
 1249                       << "TotalCallCreated" << stat_delimiter
 1250                       << "CurrentCall" << stat_delimiter
 1251                       << "SuccessfulCall(P)" << stat_delimiter
 1252                       << "SuccessfulCall(C)" << stat_delimiter
 1253                       << "FailedCall(P)" << stat_delimiter
 1254                       << "FailedCall(C)" << stat_delimiter
 1255                       << "FailedCannotSendMessage(P)" << stat_delimiter
 1256                       << "FailedCannotSendMessage(C)" << stat_delimiter
 1257                       << "FailedMaxUDPRetrans(P)" << stat_delimiter
 1258                       << "FailedMaxUDPRetrans(C)" << stat_delimiter
 1259                       << "FailedUnexpectedMessage(P)" << stat_delimiter
 1260                       << "FailedUnexpectedMessage(C)" << stat_delimiter
 1261                       << "FailedCallRejected(P)" << stat_delimiter
 1262                       << "FailedCallRejected(C)" << stat_delimiter
 1263                       << "FailedCmdNotSent(P)" << stat_delimiter
 1264                       << "FailedCmdNotSent(C)" << stat_delimiter
 1265                       << "FailedRegexpDoesntMatch(P)" << stat_delimiter
 1266                       << "FailedRegexpDoesntMatch(C)" << stat_delimiter
 1267                       << "FailedRegexpHdrNotFound(P)" << stat_delimiter
 1268                       << "FailedRegexpHdrNotFound(C)" << stat_delimiter
 1269                       << "FailedOutboundCongestion(P)" << stat_delimiter
 1270                       << "FailedOutboundCongestion(C)" << stat_delimiter
 1271                       << "FailedTimeoutOnRecv(P)" << stat_delimiter
 1272                       << "FailedTimeoutOnRecv(C)" << stat_delimiter
 1273                       << "FailedTimeoutOnSend(P)" << stat_delimiter
 1274                       << "FailedTimeoutOnSend(C)" << stat_delimiter
 1275                       << "OutOfCallMsgs(P)" << stat_delimiter
 1276                       << "OutOfCallMsgs(C)" << stat_delimiter
 1277                       << "Retransmissions(P)" << stat_delimiter
 1278                       << "Retransmissions(C)" << stat_delimiter
 1279                       << "AutoAnswered(P)" << stat_delimiter
 1280                       << "AutoAnswered(C)" << stat_delimiter;
 1281 
 1282     for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1283       char s_P[30];
 1284       char s_C[30];
 1285 
 1286       if (!rtd_stopped[i]) {
 1287   continue;
 1288       }
 1289 
 1290       sprintf(s_P, "ResponseTime%d(P)%s", i + 1, stat_delimiter);
 1291       sprintf(s_C, "ResponseTime%d(C)%s", i + 1, stat_delimiter);
 1292 
 1293       (*M_outputStream) << s_P << s_C;
 1294 
 1295       sprintf(s_P, "ResponseTime%dStDev(P)%s", i + 1, stat_delimiter);
 1296       sprintf(s_C, "ResponseTime%dStDev(C)%s", i + 1, stat_delimiter);
 1297 
 1298       (*M_outputStream) << s_P << s_C;
 1299     }
 1300 
 1301     (*M_outputStream) << "CallLength(P)" << stat_delimiter
 1302                       << "CallLength(C)" << stat_delimiter;
 1303     (*M_outputStream) << "CallLengthStDev(P)" << stat_delimiter
 1304                       << "CallLengthStDev(C)" << stat_delimiter;
 1305     for (int i = 0; i < MAX_COUNTER; i++) {
 1306       (*M_outputStream) << "GenericCounter" << (i + 1) << "(P)" << stat_delimiter;
 1307       (*M_outputStream) << "GenericCounter" << (i + 1) << "(C)" << stat_delimiter;
 1308     }
 1309     for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1310       char s[30];
 1311 
 1312       if (!rtd_stopped[i]) {
 1313   continue;
 1314       }
 1315 
 1316       sprintf(s, "ResponseTimeRepartition%d", i + 1);
 1317       (*M_outputStream) << sRepartitionHeader(M_ResponseTimeRepartition[i],
 1318                 M_SizeOfResponseTimeRepartition,
 1319                 s);
 1320     }
 1321     (*M_outputStream) << sRepartitionHeader(M_CallLengthRepartition,
 1322                                             M_SizeOfCallLengthRepartition,
 1323                                             (char*) "CallLengthRepartition");
 1324     (*M_outputStream) << endl;
 1325     M_headerAlreadyDisplayed = true;
 1326   }
 1327 
 1328   // content
 1329   (*M_outputStream) << formatTime(&M_startTime)               << stat_delimiter;
 1330   (*M_outputStream) << formatTime(&M_plStartTime)             << stat_delimiter;
 1331   (*M_outputStream) << formatTime(&currentTime)               << stat_delimiter
 1332                     << msToHHMMSS(localElapsedTime)           << stat_delimiter;
 1333   (*M_outputStream) << msToHHMMSS(globalElapsedTime)          << stat_delimiter
 1334                     << realInstantCallRate                    << stat_delimiter
 1335                     << averageCallRate                        << stat_delimiter
 1336                     << M_counters[CPT_PL_IncomingCallCreated] << stat_delimiter
 1337                     << M_counters[CPT_C_IncomingCallCreated]  << stat_delimiter
 1338                     << M_counters[CPT_PL_OutgoingCallCreated] << stat_delimiter
 1339                     << M_counters[CPT_C_OutgoingCallCreated]  << stat_delimiter
 1340                     << (M_counters[CPT_C_IncomingCallCreated]+
 1341                         M_counters[CPT_C_OutgoingCallCreated])<< stat_delimiter
 1342                     << M_counters[CPT_C_CurrentCall]          << stat_delimiter
 1343                     << M_counters[CPT_PL_SuccessfulCall]      << stat_delimiter
 1344                     << M_counters[CPT_C_SuccessfulCall]       << stat_delimiter
 1345                     << M_counters[CPT_PL_FailedCall]          << stat_delimiter
 1346                     << M_counters[CPT_C_FailedCall]           << stat_delimiter
 1347                     << M_counters[CPT_PL_FailedCallCannotSendMessage]   << stat_delimiter
 1348                     << M_counters[CPT_C_FailedCallCannotSendMessage]    << stat_delimiter
 1349                     << M_counters[CPT_PL_FailedCallMaxUdpRetrans]       << stat_delimiter
 1350                     << M_counters[CPT_C_FailedCallMaxUdpRetrans     ]   << stat_delimiter
 1351                     << M_counters[CPT_PL_FailedCallUnexpectedMessage]   << stat_delimiter
 1352                     << M_counters[CPT_C_FailedCallUnexpectedMessage]    << stat_delimiter
 1353                     << M_counters[CPT_PL_FailedCallCallRejected]        << stat_delimiter
 1354                     << M_counters[CPT_C_FailedCallCallRejected]         << stat_delimiter
 1355                     << M_counters[CPT_PL_FailedCallCmdNotSent]          << stat_delimiter
 1356                     << M_counters[CPT_C_FailedCallCmdNotSent]           << stat_delimiter
 1357                     << M_counters[CPT_PL_FailedCallRegexpDoesntMatch]   << stat_delimiter
 1358                     << M_counters[CPT_C_FailedCallRegexpDoesntMatch]    << stat_delimiter
 1359                     << M_counters[CPT_PL_FailedCallRegexpHdrNotFound]   << stat_delimiter
 1360                     << M_counters[CPT_C_FailedCallRegexpHdrNotFound]    << stat_delimiter
 1361                     << M_counters[CPT_PL_FailedOutboundCongestion]      << stat_delimiter
 1362                     << M_counters[CPT_C_FailedOutboundCongestion]       << stat_delimiter
 1363                     << M_counters[CPT_PL_FailedTimeoutOnRecv]           << stat_delimiter
 1364                     << M_counters[CPT_C_FailedTimeoutOnRecv]            << stat_delimiter
 1365                     << M_counters[CPT_PL_FailedTimeoutOnSend]           << stat_delimiter
 1366                     << M_counters[CPT_C_FailedTimeoutOnSend]            << stat_delimiter
 1367                     << M_counters[CPT_PL_OutOfCallMsgs]                 << stat_delimiter
 1368                     << M_counters[CPT_C_OutOfCallMsgs]                  << stat_delimiter
 1369                     << M_counters[CPT_PL_Retransmissions]               << stat_delimiter
 1370                     << M_counters[CPT_C_Retransmissions]                << stat_delimiter
 1371                     << M_counters[CPT_PL_AutoAnswered]                  << stat_delimiter
 1372                     << M_counters[CPT_C_AutoAnswered]                   << stat_delimiter;
 1373 
 1374   // SF917289 << M_counters[CPT_C_UnexpectedMessage]    << stat_delimiter;
 1375   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1376     if (!rtd_stopped[i]) {
 1377       continue;
 1378     }
 1379 
 1380     (*M_outputStream)
 1381       << msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_PL_AverageResponseTime_Sum + i),
 1382             (E_CounterName)(CPT_PL_NbOfCallUsedForAverageResponseTime + i))) << stat_delimiter;
 1383     (*M_outputStream)
 1384       << msToHHMMSSmmm( (unsigned long)computeMean((E_CounterName)(CPT_C_AverageResponseTime_Sum + i),
 1385             (E_CounterName)(CPT_C_NbOfCallUsedForAverageResponseTime + i))) << stat_delimiter;
 1386 
 1387     (*M_outputStream)
 1388       << msToHHMMSSmmm( (unsigned long)computeStdev((E_CounterName)(CPT_PL_AverageResponseTime_Sum + i),
 1389              (E_CounterName)(CPT_PL_NbOfCallUsedForAverageResponseTime + i),
 1390              (E_CounterName)(CPT_PL_AverageResponseTime_Squares + i)) ) << stat_delimiter;
 1391     (*M_outputStream)
 1392       << msToHHMMSSmmm( (unsigned long)computeStdev((E_CounterName)(CPT_C_AverageResponseTime_Sum + i),
 1393              (E_CounterName)(CPT_C_NbOfCallUsedForAverageResponseTime + i),
 1394              (E_CounterName)(CPT_C_AverageResponseTime_Squares + i)) ) << stat_delimiter;
 1395   }
 1396   (*M_outputStream)
 1397     << msToHHMMSSmmm( (unsigned long)computeMean(CPT_PL_AverageCallLength_Sum, CPT_PL_NbOfCallUsedForAverageCallLength) ) << stat_delimiter;
 1398   (*M_outputStream)
 1399     << msToHHMMSSmmm( (unsigned long)computeMean(CPT_C_AverageCallLength_Sum, CPT_C_NbOfCallUsedForAverageCallLength) ) << stat_delimiter;
 1400   (*M_outputStream)
 1401     << msToHHMMSSmmm( (unsigned long)computeStdev(CPT_PL_AverageCallLength_Sum,
 1402            CPT_PL_NbOfCallUsedForAverageCallLength,
 1403            CPT_PL_AverageCallLength_Squares )) << stat_delimiter;
 1404   (*M_outputStream)
 1405     << msToHHMMSSmmm( (unsigned long)computeStdev(CPT_C_AverageCallLength_Sum,
 1406            CPT_C_NbOfCallUsedForAverageCallLength,
 1407            CPT_C_AverageCallLength_Squares )) << stat_delimiter;
 1408 
 1409   for (int i = 0; i < MAX_COUNTER; i++) {
 1410     (*M_outputStream) << M_counters[CPT_PL_Generic + i] << stat_delimiter;
 1411     (*M_outputStream) << M_counters[CPT_C_Generic + i] << stat_delimiter;
 1412   }
 1413 
 1414   for (int i = 0; i < MAX_RTD_INFO_LENGTH; i++) {
 1415     if (!rtd_stopped[i]) {
 1416       continue;
 1417     }
 1418     (*M_outputStream)
 1419       << sRepartitionInfo(M_ResponseTimeRepartition[i],
 1420                           M_SizeOfResponseTimeRepartition);
 1421   }
 1422   (*M_outputStream)
 1423     << sRepartitionInfo(M_CallLengthRepartition,
 1424                         M_SizeOfCallLengthRepartition);
 1425   (*M_outputStream) << endl;
 1426 
 1427   // flushing the output file to let the tail -f working !
 1428   (*M_outputStream).flush();
 1429 
 1430 } /* end of logData () */
 1431 
 1432 void CStat::dumpDataRtt ()
 1433 {
 1434   if(M_outputStreamRtt == NULL) {
 1435     // if the file is still not opened, we opened it now
 1436     M_outputStreamRtt = new ofstream(M_fileNameRtt);
 1437     M_headerAlreadyDisplayedRtt = false;
 1438 
 1439     if(M_outputStreamRtt == NULL) {
 1440       cerr << "Unable to open rtt file '" << M_fileNameRtt << "' !" << endl;
 1441       exit(EXIT_FATAL_ERROR);
 1442     }
 1443 
 1444 #ifndef __osf__
 1445     if(!M_outputStreamRtt->is_open())
 1446       {
 1447         cerr << "Unable to open rtt file '" << M_fileNameRtt << "' !" << endl;
 1448         exit(EXIT_FATAL_ERROR);
 1449       }
 1450 #endif
 1451   }
 1452 
 1453   if(M_headerAlreadyDisplayedRtt == false) {
 1454     (*M_outputStreamRtt) << "Date_ms" << stat_delimiter
 1455       << "response_time_ms" << stat_delimiter
 1456       << "rtd_no" << endl;
 1457     M_headerAlreadyDisplayedRtt = true;
 1458   }
 1459 
 1460   for (unsigned int L_i = 0; L_i < M_counterDumpRespTime ; L_i ++) {
 1461     (*M_outputStreamRtt) <<  M_dumpRespTime[L_i].date   << stat_delimiter ;
 1462     (*M_outputStreamRtt) <<  M_dumpRespTime[L_i].rtt    << stat_delimiter ;
 1463     (*M_outputStreamRtt) <<  M_dumpRespTime[L_i].rtd_no << endl;
 1464     (*M_outputStreamRtt).flush();
 1465     M_dumpRespTime[L_i].date = 0.0;
 1466     M_dumpRespTime[L_i].rtt = 0.0;
 1467     M_dumpRespTime[L_i].rtd_no = 0;
 1468   }
 1469 
 1470   // flushing the output file
 1471   (*M_outputStreamRtt).flush();
 1472 
 1473   M_counterDumpRespTime = 0;
 1474 }
 1475 
 1476 
 1477 /* Time Gestion */
 1478 char* CStat::msToHHMMSS (unsigned long P_ms)
 1479 {
 1480   static char L_time [TIME_LENGTH];
 1481   unsigned long hh, mm, ss;
 1482 
 1483   P_ms = P_ms / 1000;
 1484   hh = P_ms / 3600;
 1485   mm = (P_ms - hh * 3600) / 60;
 1486   ss = P_ms - (hh * 3600) - (mm * 60);
 1487   sprintf (L_time, "%2.2lu:%2.2lu:%2.2lu", hh, mm, ss);
 1488   return (L_time);
 1489 } /* end of msToHHMMSS */
 1490 
 1491 char* CStat::msToHHMMSSmmm (unsigned long P_ms)
 1492 {
 1493   static char L_time [TIME_LENGTH];
 1494   unsigned long sec, hh, mm, ss, mmm;
 1495 
 1496   sec  = P_ms / 1000;
 1497   hh   = sec / 3600;
 1498   mm   = (sec - hh * 3600) / 60;
 1499   ss   = sec - (hh * 3600) - (mm * 60);
 1500   mmm  = P_ms - (hh * 3600000) - (mm * 60000) - (ss*1000);
 1501   sprintf (L_time, "%2.2lu:%2.2lu:%2.2lu:%3.3lu", hh, mm, ss, mmm);
 1502   return (L_time);
 1503 } /* end of msToHHMMSS */
 1504 
 1505 char* CStat::formatTime (struct timeval* P_tv, bool microseconds)
 1506 {
 1507   static char L_time [TIME_LENGTH];
 1508   struct tm * L_currentDate;
 1509 
 1510   // Get the current date and time
 1511   L_currentDate = localtime ((const time_t *)&P_tv->tv_sec);
 1512 
 1513   // Format the time
 1514   if (L_currentDate == NULL)
 1515     {
 1516       memset (L_time, 0, TIME_LENGTH);
 1517     }
 1518   else
 1519     {
 1520   if (microseconds) {
 1521     sprintf(L_time, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d:%03.03f",
 1522         L_currentDate->tm_year + 1900,
 1523         L_currentDate->tm_mon + 1,
 1524         L_currentDate->tm_mday,
 1525         L_currentDate->tm_hour,
 1526         L_currentDate->tm_min,
 1527         L_currentDate->tm_sec,
 1528         (double)P_tv->tv_usec/(double)1000.0);
 1529   } else {
 1530           sprintf(L_time, "%4.4d-%2.2d-%2.2d\t%2.2d:%2.2d:%2.2d:%3.3d\t%10.10d.%6.6d",
 1531         L_currentDate->tm_year + 1900,
 1532         L_currentDate->tm_mon + 1,
 1533         L_currentDate->tm_mday,
 1534         L_currentDate->tm_hour,
 1535         L_currentDate->tm_min,
 1536         L_currentDate->tm_sec,
 1537               (int) (P_tv->tv_usec)/1000,
 1538               (long) (P_tv->tv_sec),
 1539               (long) (P_tv->tv_usec));
 1540   }
 1541     }
 1542   return (L_time);
 1543 } /* end of formatTime */
 1544 
 1545 long CStat::computeDiffTimeInMs (struct timeval* tf, struct timeval* ti)
 1546 {
 1547   long v1, v2;
 1548 
 1549   v1 = tf->tv_sec - ti->tv_sec;
 1550   v2 = tf->tv_usec - ti->tv_usec;
 1551   if (v2 < 0) v2 += 1000000, v1--;
 1552   return (v1*1000 + v2/1000);
 1553 }
 1554 
 1555 
 1556 CStat* CStat::M_instance = NULL;
 1557 
 1558 /* Implementation of a fixed distribution. */
 1559 CFixed::CFixed(double value) {
 1560   this->value = value;
 1561 }
 1562 double CFixed::sample() {
 1563   return value;
 1564 }
 1565 int CFixed::textDescr(char *s, int len) {
 1566   return snprintf(s, len, "%lf", value);
 1567 }
 1568 int CFixed::timeDescr(char *s, int len) {
 1569   return time_string(value, s, len);
 1570 }
 1571 double CFixed::cdfInv(double percentile) {
 1572   return value;
 1573 }
 1574 
 1575 /* Implementation of the default pause time. */
 1576 CDefaultPause::CDefaultPause() {
 1577 }
 1578 double CDefaultPause::sample() {
 1579   return (double)duration;
 1580 }
 1581 int CDefaultPause::textDescr(char *s, int len) {
 1582   return snprintf(s, len, "%d", duration);
 1583 }
 1584 int CDefaultPause::timeDescr(char *s, int len) {
 1585   return time_string(duration, s, len);
 1586 }
 1587 double CDefaultPause::cdfInv(double percentile) {
 1588   return duration;
 1589 }
 1590 
 1591 /* Implementation of a uniform distribution. */
 1592 static bool uniform_init = false;
 1593 CUniform::CUniform(double min, double max) {
 1594   if (!uniform_init) {
 1595     uniform_init = true;
 1596     srand(time(NULL));
 1597   }
 1598   this->min = min;
 1599   this->max = max;
 1600 }
 1601 double CUniform::sample() {
 1602   double rval = ((double)rand())/((double)RAND_MAX);
 1603   return min + (rval * (max - min));
 1604 }
 1605 int CUniform::textDescr(char *s, int len) {
 1606   return snprintf(s, len, "%lf/%lf", min, max);
 1607 }
 1608 int CUniform::timeDescr(char *s, int len) {
 1609   int used = time_string(min, s, len);
 1610   used += snprintf(s + used, len - used, "/");
 1611   used += time_string(max, s + used, len - used);
 1612   return used;
 1613 }
 1614 double CUniform::cdfInv(double percentile) {
 1615   return min + (max * percentile);
 1616 }
 1617 
 1618 #ifdef HAVE_GSL
 1619 gsl_rng *gsl_init() {
 1620   static gsl_rng *rng = NULL;
 1621 
 1622   if (rng) {
 1623     return rng;
 1624   }
 1625 
 1626   gsl_rng_env_setup();
 1627   rng = gsl_rng_alloc(gsl_rng_default);
 1628   if (!rng) {
 1629     ERROR("Could not initialize GSL random number generator.\n");
 1630   }
 1631 
 1632   return rng;
 1633 }
 1634 
 1635 /* Normal distribution. */
 1636 CNormal::CNormal(double mean, double stdev) {
 1637   this->mean = mean;
 1638   this->stdev = stdev;
 1639   rng = gsl_init();
 1640 }
 1641 
 1642 double CNormal::sample() {
 1643   double val = gsl_ran_gaussian(rng, stdev);
 1644   return val + mean;
 1645 }
 1646 
 1647 int CNormal::textDescr(char *s, int len) {
 1648   return snprintf(s, len, "N(%.3lf,%.3lf)", mean, stdev);
 1649 }
 1650 int CNormal::timeDescr(char *s, int len) {
 1651   int used = 0;
 1652 
 1653   used += snprintf(s, len, "N(");
 1654   used += time_string(mean, s + used, len - used);
 1655   used += snprintf(s + used, len - used, ",");
 1656   used += time_string(stdev, s + used, len - used);
 1657   used += snprintf(s + used, len - used, ")");
 1658 
 1659   return used;
 1660 }
 1661 double CNormal::cdfInv(double percentile) {
 1662   return mean + gsl_cdf_gaussian_Pinv(percentile, stdev);
 1663 }
 1664 
 1665 /* Lognormal distribution. */
 1666 double CLogNormal::sample() {
 1667   return gsl_ran_lognormal(rng, mean, stdev);
 1668 }
 1669 int CLogNormal::textDescr(char *s, int len) {
 1670   if (len == 0)
 1671     return 0;
 1672   s[0] = 'L';
 1673   return 1 + this->CNormal::textDescr(s + 1, len - 1);
 1674 }
 1675 int CLogNormal::timeDescr(char *s, int len) {
 1676   if (len == 0)
 1677     return 0;
 1678   s[0] = 'L';
 1679   return 1 + this->CNormal::timeDescr(s + 1, len - 1);
 1680 }
 1681 double CLogNormal::cdfInv(double percentile) {
 1682   return gsl_cdf_lognormal_Pinv(percentile, mean, stdev);
 1683 }
 1684 
 1685 /* Exponential distribution. */
 1686 CExponential::CExponential(double mean) {
 1687   this->mean = mean;
 1688   rng = gsl_init();
 1689 }
 1690 
 1691 double CExponential::sample() {
 1692   return gsl_ran_exponential(rng, mean);
 1693 }
 1694 
 1695 int CExponential::textDescr(char *s, int len) {
 1696   return snprintf(s, len, "Exp(%lf)", mean);
 1697 }
 1698 int CExponential::timeDescr(char *s, int len) {
 1699   int used = snprintf(s, len, "Exp(");
 1700   used += time_string(mean, s + used, len - used);
 1701   used += snprintf(s + used, len - used, ")");
 1702   return used;
 1703 }
 1704 double CExponential::cdfInv(double percentile) {
 1705   return gsl_cdf_exponential_Pinv(percentile, mean);
 1706 }
 1707 
 1708 /* Weibull distribution. */
 1709 CWeibull::CWeibull(double lambda, double k) {
 1710   this->lambda = lambda;
 1711   this->k = k;
 1712   rng = gsl_init();
 1713 }
 1714 
 1715 double CWeibull::sample() {
 1716   return gsl_ran_weibull(rng, lambda, k);
 1717 }
 1718 
 1719 int CWeibull::textDescr(char *s, int len) {
 1720   return snprintf(s, len, "Wb(%.3lf,%.3lf)", lambda, k);
 1721 }
 1722 int CWeibull::timeDescr(char *s, int len) {
 1723   int used = 0;
 1724 
 1725   used += snprintf(s, len, "Wb(");
 1726   used += time_string(lambda, s + used, len - used);
 1727   used += snprintf(s + used, len - used, ",");
 1728   used += time_string(k, s + used, len - used);
 1729   used += snprintf(s + used, len - used, ")");
 1730 
 1731   return used;
 1732 }
 1733 double CWeibull::cdfInv(double percentile) {
 1734   return gsl_cdf_weibull_Pinv(percentile, lambda, k);
 1735 }
 1736 
 1737 /* Pareto distribution. */
 1738 CPareto::CPareto(double k, double xsubm) {
 1739   this->k = k;
 1740   this->xsubm = xsubm;
 1741   rng = gsl_init();
 1742 }
 1743 
 1744 double CPareto::sample() {
 1745   return gsl_ran_pareto(rng, k, xsubm);
 1746 }
 1747 
 1748 int CPareto::textDescr(char *s, int len) {
 1749   return snprintf(s, len, "P(%.3lf,%.3lf)", k, xsubm);
 1750 }
 1751 int CPareto::timeDescr(char *s, int len) {
 1752   int used = 0;
 1753 
 1754   used += snprintf(s, len, "P(");
 1755   used += time_string(k, s + used, len - used);
 1756   used += snprintf(s + used, len - used, ",");
 1757   used += time_string(xsubm, s + used, len - used);
 1758   used += snprintf(s + used, len - used, ")");
 1759 
 1760   return used;
 1761 }
 1762 double CPareto::cdfInv(double percentile) {
 1763   return gsl_cdf_pareto_Pinv(percentile, k, xsubm);
 1764 }
 1765 
 1766 /* Gamma distribution. */
 1767 CGamma::CGamma(double k, double theta) {
 1768   this->k = k;
 1769   this->theta = theta;
 1770   rng = gsl_init();
 1771 }
 1772 
 1773 double CGamma::sample() {
 1774   return gsl_ran_gamma(rng, k, theta);
 1775 }
 1776 
 1777 int CGamma::textDescr(char *s, int len) {
 1778   return snprintf(s, len, "G(%.3lf,%.3lf)", k, theta);
 1779 }
 1780 int CGamma::timeDescr(char *s, int len) {
 1781   int used = 0;
 1782 
 1783   used += snprintf(s, len, "G(");
 1784   used += time_string(k, s + used, len - used);
 1785   used += snprintf(s + used, len - used, ",");
 1786   used += time_string(theta, s + used, len - used);
 1787   used += snprintf(s + used, len - used, ")");
 1788 
 1789   return used;
 1790 }
 1791 double CGamma::cdfInv(double percentile) {
 1792   return gsl_cdf_gamma_Pinv(percentile, k, theta);
 1793 }
 1794 
 1795 /* NegBin distribution. */
 1796 CNegBin::CNegBin(double p, double n) {
 1797   this->p = p;
 1798   this->n = n;
 1799   rng = gsl_init();
 1800 }
 1801 
 1802 double CNegBin::sample() {
 1803   return gsl_ran_negative_binomial(rng, n, p);
 1804 }
 1805 
 1806 int CNegBin::textDescr(char *s, int len) {
 1807   return snprintf(s, len, "NB(%.3lf,%.3lf)", p, n);
 1808 }
 1809 int CNegBin::timeDescr(char *s, int len) {
 1810   int used = 0;
 1811 
 1812   used += snprintf(s, len, "NB(");
 1813   used += time_string(p, s + used, len - used);
 1814   used += snprintf(s + used, len - used, ",");
 1815   used += time_string(n, s + used, len - used);
 1816   used += snprintf(s + used, len - used, ")");
 1817 
 1818   return used;
 1819 }
 1820 /* We really don't implement this, but should so that sanity checking will
 1821  * work. For now, just return zero. */
 1822 double CNegBin::cdfInv(double percentile) {
 1823   return 0;
 1824 }
 1825 #endif
 1826 
 1827 

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8