📄 delirpt.c
字号:
/***************************
delirpt.c
***************************
/* FILE: DELIRPT.C
* Microsoft TPC-C Kit Ver.
3.00.000
*
* Copyright Microsoft, 1996
*
* PURPOSE: Delivery report processing application
* Author: Philip Durr
* philipdu@Microsoft.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LOGFILE_READ_EOF 0
//check log file flag return current state
#define LOGFILE_CLEAR_EOF 1
//clear end of log file flag
#define LOGFILE_SET_EOF 2
//set flag end of log file reached
#define INTERVAL .01
//90th percentile calculation bucket interval
#define ERR_SUCCESS 1000
//success no error
#define ERR_READING_LOGFILE 1001
//io errors occured reading delivery log file
#define ERR_INSUFFICIENT_MEMORY 1002
//insuficient memory to process 90th percentile report
#define ERR_CANNOT_OPEN_RESULTS_FILE 1005
//Cannot open delivery results file delilog.
#define TRUE 1
#define FALSE 0
typedef int BOOL;
typedef struct _DelTime
{
struct tm dtime;
int wMilliseconds;
} DelTime;
typedef struct _RPTLINE
{
DelTime start;
//delilog report line start time
DelTime end;
//delilog report line end time
int response;
//delilog report line time delivery took in milliseconds
int w_id;
//delilog report line warehouse id for delivery
int o_carrier_id;
//delilog report line carier id for delivery
int items[10];
//delilog report line delivery line items
int day;
} RPTLINE, *PRPTLINE;
//error message structure used in ErrorMessage API
typedef struct _SERRORMSG
{
int iError;
//error id of message
char szMsg[80];
//message to sent to browser
} SERRORMSG;
int versionMS = 3;
//delirpt version
int versionMM = 0;
int versionLS = 2;
int iReport;
//delirpt report to process
int iStartTime;
//begin times to accept for report
int iEndTime;
//end times to accept for report
int StartDay;
int OverMidnight=0;
FILE *fpLog;
//log file stream
//Local function prototypes
int main(int argc, char *argv[]);
static int Init(void);
static void Restore(void);
static int DoReport(void);
int AverageResponse(void);
int SkippedDelivery(void);
int Percentile90th(void);
int CheckTimes(PRPTLINE pRptLine);
static int OpenLogFile(void);
static void CloseLogFile(void);
static void ResetLogFile(void);
static BOOL LogEOF(int iOperation);
static BOOL ReadReportLine(char *szBuffer, PRPTLINE pRptLine);
static BOOL ParseReportLine(char *szLine, PRPTLINE pRptLine);
static BOOL ParseDate(char *szDate, DelTime *pTime);
static BOOL ParseTime(char *szTime, DelTime *pTime);
static void ErrorMessage(int iError);
static BOOL GetParameters(int argc, char *argv[]);
static void PrintParameters(void);
static void cls(void);
static BOOL IsNumeric(char *ptr);
/* FUNCTION: int main(int argc, char *argv[])
*
* PURPOSE: This function is the beginning execution point for the delivery executable.
*
* ARGUMENTS: int argc number of command line arguments passed to delivery
* char *argv[] array of command line argument pointers
*
* RETURNS: None
*
* COMMENTS: None
*
*/
int main(int argc, char *argv[])
{
int iError;
if ( GetParameters(argc, argv) )
{
PrintParameters();
return -1;
}
if ( (iError=Init()) != ERR_SUCCESS )
{
ErrorMessage(iError);
Restore();
return -1;
}
if ( (iError = DoReport()) != ERR_SUCCESS )
ErrorMessage(iError);
Restore();
return 0;
}
/* FUNCTION: static int Init(void)
*
* PURPOSE: This function initializes the delirtp application.
*
* ARGUMENTS: None
*
* RETURNS: None
*
* COMMENTS: None
*
*/
static int Init(void)
{
int iError;
if ( (iError = OpenLogFile()) )
return iError;
return TRUE;
}
/* FUNCTION: static void Restore(void)
*
* PURPOSE: This function cleans up the delirpt application before termination.
*
* ARGUMENTS: None
*
* RETURNS: None
*
* COMMENTS: None
*
*/
static void Restore(void)
{
CloseLogFile();
return;
}
/* FUNCTION: static int DoReport(void)
*
* PURPOSE: This function dispatches the requested report.
*
* ARGUMENTS: None
*
* RETURNS: ERR_SUCCESS if successfull or error code if an error occurs.
*
* COMMENTS: None
*
*/
static int DoReport(void)
{
int iRc;
switch(iReport)
{
case 1:
iRc = AverageResponse();
break;
case 2:
iRc = Percentile90th();
break;
case 3:
iRc = SkippedDelivery();
break;
case 4:
if ( (iRc = AverageResponse()) != ERR_SUCCESS )
break;
if ( (iRc = Percentile90th()) != ERR_SUCCESS )
break;
if ( (iRc = SkippedDelivery()) != ERR_SUCCESS )
break;
break;
}
return iRc;
}
/* FUNCTION: int AverageResponse(void)
*
* PURPOSE: This function processes the AverageResponse report.
*
* ARGUMENTS: None
*
* RETURNS: ERR_SUCCESS if successfull or error code if an error occurs.
*
* COMMENTS: None
*
*/
int AverageResponse(void)
{
RPTLINE reportLine;
unsigned long iTotalResponse;
unsigned long iLines;
double fAverage;
char szDelivery[128];
ResetLogFile();
iTotalResponse = 0;
iLines = 0;
printf("\n\n******** Average Response Time Report*******\n");
while ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( ReadReportLine(szDelivery, &reportLine) )
return ERR_READING_LOGFILE;
if ( szDelivery[0] == '*' )
continue;
if ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( CheckTimes(&reportLine) )
continue;
iLines++;
iTotalResponse += reportLine.response;
if ( iLines % 10 == 0 )
printf("Reading Report Line:\t%d\r", iLines);
}
}
printf(" \r");
if ( iLines == 0 )
{
printf("No deliveries found.\n");
}
else
{
fAverage = (iTotalResponse / iLines)/1000.0;
printf("Total Deliveries: %u\n", iLines);
printf("Total Response Times: %10.3f (sec)\n",(iTotalResponse/1000.0));
printf("Average Response Time: %10.3f (sec)\n",fAverage);
}
return ERR_SUCCESS;
}
/* FUNCTION: int Percentile90th(void)
*
* PURPOSE: This function processes the 90th percentile report.
*
* ARGUMENTS: None
*
* RETURNS: ERR_SUCCESS if successfull or error code if an error occurs.
*
* COMMENTS: This function requires enough space to allocate needed
* buckets which will be 2 * max response time in
* deci-seconds.
*
*/
int Percentile90th(void)
{
RPTLINE reportLine;
int iBucketSize;
int i;
long iMaxSeconds;
int iTotalBuckets;
double iTotal;
double i90thPercent;
short *psBuckets;
char szDelivery[128];
printf("\n\n******** 90th Percentile *******\n");
printf("Calculating Max Response Seconds...\n");
ResetLogFile();
iMaxSeconds = -1;
while ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( ReadReportLine(szDelivery, &reportLine) )
return ERR_READING_LOGFILE;
if ( szDelivery[0] == '*' )
continue;
if ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( iMaxSeconds <reportLine.response )
iMaxSeconds = reportLine.response;
}
}
iTotalBuckets = iMaxSeconds + 1;
printf("Allocating Buckets...\n");
iBucketSize = iTotalBuckets * sizeof(short);
if ( !(psBuckets = (short *)malloc(iBucketSize)) )
return ERR_INSUFFICIENT_MEMORY;
/*
ZeroMemory(psBuckets, iBucketSize);
*/
iTotal = 0;
ResetLogFile();
printf("Calculating Distribution...\n");
while ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( ReadReportLine(szDelivery, &reportLine) )
return ERR_READING_LOGFILE;
if ( szDelivery[0] == '*' )
continue;
if ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( CheckTimes(&reportLine) )
continue;
psBuckets[reportLine.response]++;
iTotal++;
}
}
i90thPercent = iTotal * .9;
for(i=0, iTotal = 0.0; iTotal < i90thPercent; iTotal += (double)psBuckets[i] )
i++;
printf("90th Percentile = %d.%d\n", i/1000, (i % 1000));
free(psBuckets);
return ERR_SUCCESS;
}
/* FUNCTION: int SkippedDelivery(void)
*
* PURPOSE: This function processes the Skipped Deliveries report.
*
* ARGUMENTS: None
*
* RETURNS: ERR_SUCCESS if successfull or error code if an error occurs.
*
* COMMENTS: None
*
*/
int SkippedDelivery(void)
{
RPTLINE reportLine;
char szDelivery[128];
int i;
int items[10];
ResetLogFile();
printf("\n\n******** Skipped Delivery Report *******\n");
memset(items, 0, sizeof(items));
printf("Reading Delivery Log File...");
while ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( ReadReportLine(szDelivery, &reportLine) )
return ERR_READING_LOGFILE;
if ( szDelivery[0] == '*' )
continue;
if ( !LogEOF(LOGFILE_READ_EOF) )
{
if ( CheckTimes(&reportLine) )
continue;
for(i=0; i<10; i++)
{
if ( !reportLine.items[i] )
items[i]++;
}
}
}
printf("\n");
printf("Skipped delivery table.\n");
printf(" 1 2 3 4 5 6 7 8 9 10 \n");
printf("---- ---- ---- ---- ---- ---- ---- ---- ---- ---- \n");
for(i=0; i<10; i++)
printf("%4.4d ", items[i]);
printf("\n");
return ERR_SUCCESS;
}
/* FUNCTION: BOOL CheckTimes(PRPTLINE pRptLine)
*
* PURPOSE: This function checks to see of the delilog record falls withing the
* begin and end time from the command line.
*
* ARGUMENTS: PRPTLINE pRptLine delilog processed report line.
*
* RETURNS: BOOL FALSE if report line is not within the
* requested start and end times.
* TRUE if the report line is within the
* requested start and end times.
*
* COMMENTS: If startTime and endTime are both 0 then the user requested
* the default behavior which is all records in delilog are
* valid.
*/
BOOL CheckTimes(PRPTLINE pRptLine)
{
int iRptEndTime;
int iRptStartTime;
iRptStartTime = (pRptLine->start.dtime.tm_hour * 3600000)
+ (pRptLine->start.dtime.tm_min * 60000) + (pRptLine->start.dtime.tm_sec * 1000)
+ pRptLine->start.wMilliseconds;
iRptEndTime = (pRptLine->end.dtime.tm_hour * 3600000) +
(pRptLine->end.dtime.tm_min * 60000) + (pRptLine->end.dtime.tm_sec * 1000)
+ pRptLine->end.wMilliseconds;
if ( iStartTime == 0 && iEndTime == 0 )
return FALSE;
if ( !OverMidnight )
{
if ( iStartTime <= iRptStartTime && iEndTime >= iRptEndTime )
return FALSE;
}
else
{
if ( pRptLine->day == StartDay )
{
if ( iStartTime <= iRptStartTime )
return FALSE;
}
else
{
if ( iEndTime >= iRptEndTime )
return FALSE;
}
}
return TRUE;
}
/* FUNCTION: int OpenLogFile(void)
*
* PURPOSE: This function opens the delivery log file for use.
*
* ARGUMENTS: None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -