You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1046 lines
24 KiB
1046 lines
24 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
|
|
|
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
#include "CardStats.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Main stats loop |
|
//----------------------------------------------------------------------------- |
|
int main( int argc, char* argv[] ) |
|
{ |
|
if ( argc != 3 ) // a unix style usage string |
|
{ |
|
printf ( "Usage: <SearchString> <Filename>\n" ); |
|
printf ( "Output file will be <filename>.<searchstring>.txt" ); |
|
return 0; |
|
} |
|
|
|
char* pszCardtype = argv[1]; // video card type we are looking for |
|
char* pszFilename = argv[2]; // file containing the data |
|
|
|
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
int nFileSize = LoadFileIntoBuffer(buf, pszFilename); |
|
|
|
ParseHeader ( buf ); |
|
|
|
CUtlBuffer output ( 0, 255, CUtlBuffer::TEXT_BUFFER ); |
|
|
|
int binwidth=100; |
|
// video card stats over time |
|
//TimeSeriesVCard ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
// cpu type stats over time |
|
//TimeSeriesCPU ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
// CPU vs Videocard |
|
//ParseFile ( buf, output, pszCardtype, nFileSize, binwidth, 0); |
|
// CPU vs Memory |
|
//ParseFile2 ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
//CPU vs network speed |
|
//ParseFile3 ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
// histogram of video card distribution |
|
HistogramVidCards ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
//HistogramNetSpeed ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
//HistogramRam ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
//HistogramCPU ( buf, output, pszCardtype, nFileSize, binwidth ); |
|
WriteOutputToFile ( output, pszFilename, pszCardtype ); |
|
|
|
return 0; |
|
} |
|
|
|
void HistogramCPU( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
ParseFile ( inbuf, outbuf, "", size, binwidth, 1 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Reads entire file contents in to utlbuffer |
|
// input-buffer to load fileinto, filename |
|
// output-filesize |
|
//----------------------------------------------------------------------------- |
|
|
|
int LoadFileIntoBuffer(CUtlBuffer &buf, char *pszFilename) |
|
{ |
|
// Open the file |
|
FILE *fh = fopen ( pszFilename, "rb" ); |
|
if (fh == NULL) |
|
{ |
|
printf ("Unable to open datafile. Check path/name."); |
|
exit( 0 ); |
|
} |
|
|
|
fseek( fh, 0, SEEK_END ); |
|
int nFileSize = ftell( fh ); |
|
fseek ( fh, 0, SEEK_SET ); |
|
|
|
// Read the file in one gulp |
|
buf.EnsureCapacity( nFileSize ); |
|
int result=fread( buf.Base(), sizeof( char ), nFileSize, fh ); |
|
fclose( fh ); |
|
buf.SeekPut( CUtlBuffer::SEEK_HEAD, result ); |
|
|
|
return nFileSize; |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Writes the contents of the utlbuffer to file |
|
// datafile name becomes name.card.txt for results |
|
//----------------------------------------------------------------------------- |
|
|
|
void WriteOutputToFile( CUtlBuffer &buf, char *pszFilename, char *pszCardtype ) |
|
{ |
|
char pszOutFilename[500]; |
|
strncpy( pszOutFilename, pszFilename, strlen( pszFilename )-3 ); |
|
pszOutFilename[strlen(pszFilename)-3]='\0'; |
|
strcat ( pszOutFilename, pszCardtype ); |
|
strcat ( pszOutFilename, ".txt\0" ); |
|
|
|
FILE *fh = fopen ( pszOutFilename, "w" ); |
|
if ( fh == NULL ) |
|
{ |
|
printf ( "Unable to open outputfile." ); |
|
exit(0); |
|
} |
|
|
|
fwrite ( buf.Base(), sizeof( char ), buf.TellPut(), fh ); |
|
fclose( fh ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Strips off header fields from datafile |
|
//----------------------------------------------------------------------------- |
|
|
|
void ParseHeader( CUtlBuffer &buf ) |
|
{ |
|
// remove first line of data (field labels) |
|
char pszTrash[256]; |
|
buf.Scanf( "%s ", pszTrash); |
|
buf.Scanf( "%s ", pszTrash); |
|
buf.Scanf( "%s ", pszTrash); |
|
buf.Scanf( "%s ", pszTrash); |
|
buf.Scanf( "%s ", pszTrash); |
|
buf.Scanf( "%s \n", pszTrash); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Counts number of users that have a given cpu bin speed for videocard string |
|
// |
|
// Parses buffer into fields and puts results into outbuf |
|
// size is size of the file read in |
|
//----------------------------------------------------------------------------- |
|
|
|
void ParseFile( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth, int nofilter) |
|
{ |
|
|
|
// Each bin is how many computers with the given card had cpus > cpubin |
|
// and less than the next bin so cpu 200 covers cpu's from 200 to 299 |
|
CUtlVector<int> nCpuList; |
|
CUtlVector<int> nQuantity; |
|
for ( int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range |
|
{ |
|
nCpuList.AddToTail(i); |
|
nQuantity.AddToTail(0); |
|
} |
|
|
|
int totalUsers=0; |
|
while ( inbuf.TellGet() < size ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[300]; |
|
int nNetSpeed, nRam, nCpu; |
|
int nRead=inbuf.Scanf( "%s %d %d %d ", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
} |
|
pszCard[i] = '\0'; |
|
|
|
if (nRead != 4) |
|
continue; |
|
|
|
// if card is our type |
|
if ( nofilter || Q_stristr ( pszCard, pszSearchString ) != NULL ) |
|
{ |
|
InsertResult(nCpu, nCpuList, nQuantity); |
|
} |
|
totalUsers++; |
|
} |
|
|
|
if (nCpuList.Size()>65000) |
|
{ |
|
printf ("Too many points, increase bin width\n"); |
|
} |
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
int total=0; |
|
outbuf.Printf ( "Cpu\tQuantity\n" ); // headers |
|
for ( int i=0; i < nCpuList.Size(); ++i ) |
|
{ |
|
outbuf.Printf ( "%d\t%d\n", nCpuList[i], nQuantity[i] ); |
|
total+=nQuantity[i]; |
|
} |
|
|
|
printf ("Users in this subset %d\n", total); |
|
printf ("Percent of dataset %.2f", ((float)total/(float)totalUsers)*100); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// given cpu bin, plots number of users in a given memory bin |
|
// |
|
// Parses buffer into fields and puts results into outbuf |
|
// size is size of the file read in |
|
//----------------------------------------------------------------------------- |
|
|
|
#define NMEMBINS 6 |
|
//#define NCPUBINS 48 // binwidth 50 |
|
#define NCPUBINS 24 // binwidth 100 |
|
|
|
void ParseFile2( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
binwidth=100; |
|
|
|
// Each bin is how many computers with the given card had cpus > cpubin |
|
// and less than the next bin so cpu 200 covers cpu's from 200 to 299 |
|
CUtlVector<int> nCpuList; |
|
CUtlVector<int> nMemList; |
|
int nQuantity[NMEMBINS][NCPUBINS]; |
|
for (int i=0; i < NMEMBINS; ++i) |
|
{ |
|
for (int j=0; j< NCPUBINS; ++j) |
|
nQuantity[i][j]=0; |
|
} |
|
|
|
for ( int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range |
|
{ |
|
nCpuList.AddToTail(i); |
|
} |
|
|
|
nMemList.AddToTail(0); |
|
int basemem=64; |
|
while ( basemem < 2050 ) |
|
{ |
|
nMemList.AddToTail(basemem); |
|
basemem<<=1; |
|
} |
|
|
|
int totalUsers=0; |
|
int maxram=0; |
|
while ( inbuf.TellGet() < size ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
// scan through the rest of the junk |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
++i; |
|
} |
|
// determine cpu bin |
|
if (nCpu < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nCpu > nCpuList[nCpuList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nCpu > nCpuList[i] ) |
|
{ |
|
++i; |
|
} |
|
int cpuIndex = i-1; |
|
assert(i<nCpuList.Size()); |
|
// determine memory bin |
|
if (nRam < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nRam > nMemList[nMemList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nRam > nMemList[i] ) |
|
{ |
|
++i; |
|
} |
|
int memIndex = i-1; |
|
assert(i<nMemList.Size()); |
|
// insert data |
|
assert(memIndex<NMEMBINS); |
|
assert(cpuIndex<NCPUBINS); |
|
(nQuantity[memIndex][cpuIndex])++; |
|
|
|
totalUsers++; |
|
//printf ("%d\n", totalUsers); |
|
if (nRam> maxram) |
|
maxram=nRam; |
|
} |
|
|
|
if (nCpuList.Size()>65000) |
|
{ |
|
printf ("Too many points, increase bin width\n"); |
|
} |
|
printf("TotalUsers %d\n", totalUsers); |
|
printf("Max ram %d\n", maxram); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "Cpu" ); // headers |
|
for (int j=1; j < nMemList.Size(); ++j) |
|
outbuf.Printf ("\tMemoryBin%d", nMemList[j]); |
|
outbuf.Printf ("\n"); |
|
|
|
for ( int i=0; i < NCPUBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "%d", nCpuList[i]); |
|
for (int j=0; j < NMEMBINS; ++j) |
|
outbuf.Printf ("\t%d", nQuantity[j][i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// given cpu bin, plots number of users in a given network speed bin |
|
// |
|
// Parses buffer into fields and puts results into outbuf |
|
// size is size of the file read in |
|
//----------------------------------------------------------------------------- |
|
|
|
#define NNETBINS 9 |
|
|
|
void ParseFile3( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
binwidth=100; |
|
|
|
// Each bin is how many computers with the given card had cpus > cpubin |
|
// and less than the next bin so cpu 200 covers cpu's from 200 to 299 |
|
CUtlVector<int> nCpuList; |
|
CUtlVector<int> nNetList; |
|
int nQuantity[NNETBINS][NCPUBINS]; |
|
for (int i=0; i < NNETBINS; ++i) |
|
{ |
|
for (int j=0; j< NCPUBINS; ++j) |
|
nQuantity[i][j]=0; |
|
} |
|
|
|
for (int i=0; i <= 2400 ; i+=binwidth) // a reasonable cpu range |
|
{ |
|
nCpuList.AddToTail(i); |
|
} |
|
|
|
nNetList.AddToTail(0); |
|
nNetList.AddToTail(28); |
|
nNetList.AddToTail(33); |
|
nNetList.AddToTail(56); |
|
nNetList.AddToTail(112); |
|
nNetList.AddToTail(256); |
|
nNetList.AddToTail(512); |
|
nNetList.AddToTail(1000); |
|
nNetList.AddToTail(2000); |
|
|
|
int totalUsers=0; |
|
int maxspeed=0; |
|
while ( inbuf.TellGet() < size ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
// scan through the rest of the junk |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
++i; |
|
} |
|
// determine cpu bin |
|
if (nCpu < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nCpu > nCpuList[nCpuList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nCpu > nCpuList[i] ) |
|
{ |
|
++i; |
|
} |
|
int cpuIndex = i-1; |
|
assert(i<nCpuList.Size()); |
|
// determine netspeed bin |
|
if (nNetSpeed < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nNetSpeed > nNetList[nNetList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nNetSpeed > nNetList[i] ) |
|
{ |
|
++i; |
|
} |
|
int netIndex = i; |
|
assert(i<nNetList.Size()); |
|
// insert data |
|
assert(netIndex<NNETBINS); |
|
assert(cpuIndex<NCPUBINS); |
|
(nQuantity[netIndex][cpuIndex])++; |
|
|
|
totalUsers++; |
|
//printf ("%d\n", totalUsers); |
|
if (nNetSpeed> maxspeed) |
|
maxspeed=nNetSpeed; |
|
} |
|
|
|
if (nCpuList.Size()>65000) |
|
{ |
|
printf ("Too many points, increase bin width\n"); |
|
} |
|
printf("TotalUsers %d\n", totalUsers); |
|
printf("Max ram %d\n", maxspeed); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "Cpu" ); // headers |
|
for (int j=0; j < nNetList.Size()-1; ++j) |
|
outbuf.Printf ("\t%d-%d", nNetList[j], nNetList[j+1]); |
|
outbuf.Printf ("\n"); |
|
|
|
for (int i=0; i < NCPUBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "%d", nCpuList[i]); |
|
for (int j=0; j < NNETBINS; ++j) |
|
outbuf.Printf ("\t%d", nQuantity[j][i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// given time bin, plots number of users in a given cpu TYPE over time, |
|
// as the numbers came into the server |
|
// |
|
// Parses buffer into fields and puts results into outbuf |
|
// size is size of the file read in |
|
//----------------------------------------------------------------------------- |
|
|
|
#define CPUBINS 3 // 0=AMD, 1=Intel, 2=Unknown |
|
#define MAXUSERS 750000 |
|
|
|
void TimeSeriesCPU( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
binwidth=600; |
|
|
|
// unequally sized bins |
|
|
|
// Each bin is how many computers with the given card had cpus > cpubin |
|
// and less than the next bin so cpu 200 covers cpu's from 200 to 299 |
|
CUtlVector<int> nTimeList; |
|
int nQuantity[30][CPUBINS]; |
|
for (int i=0; i < 30; ++i) |
|
{ |
|
for (int j=0; j< CPUBINS; ++j) |
|
nQuantity[i][j]=0; |
|
} |
|
|
|
nTimeList.AddToTail(0); |
|
int bin=10000; |
|
int i=bin; |
|
for (i; i<=MAXUSERS; i=bin) |
|
{ |
|
nTimeList.AddToTail(i); |
|
bin<<=1; |
|
} |
|
nTimeList.AddToTail(i); |
|
|
|
// for unequal bins |
|
int currentTimeBin=1; |
|
|
|
int totalUsers=0; |
|
while ( (inbuf.TellGet() < size) ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
if (i >= 300) |
|
break; |
|
} |
|
// check for those blasted hackers |
|
if (i>= 300) |
|
{ |
|
// read rest |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
} |
|
continue; |
|
} |
|
|
|
pszCard[i] = '\0'; |
|
|
|
int cpuIndex=2; // default is unknown |
|
if ( Q_stristr ( pszCard, "SSE" ) != NULL ) |
|
{ |
|
cpuIndex=1; // intel |
|
} |
|
else if ( Q_stristr ( pszCard, "KNI" ) != NULL ) |
|
{ |
|
cpuIndex=1; // intel |
|
} |
|
else if ( Q_stristr ( pszCard, "3DNOW" ) != NULL ) |
|
{ |
|
cpuIndex=0; |
|
} |
|
|
|
// update nTimeList bin if necessary |
|
if (nTimeList[currentTimeBin] <= totalUsers) |
|
{ |
|
currentTimeBin++; |
|
} |
|
|
|
nQuantity[currentTimeBin][cpuIndex]++; |
|
assert(nQuantity[currentTimeBin][cpuIndex]>0); |
|
|
|
totalUsers++; |
|
} |
|
|
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "CPU" ); // headers |
|
for (int j=1; j < nTimeList.Size(); ++j) |
|
outbuf.Printf ("\tUsersSoFar%d", nTimeList[j]); |
|
outbuf.Printf ("\n"); |
|
|
|
for (int i=0; i < CPUBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "-"); |
|
for (int j=1; j < nTimeList.Size(); ++j) // use NTIMEBINS for equal sized bins |
|
outbuf.Printf ("\t%d", nQuantity[j][i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// given time bin, plots number of users in a given video card TYPE over time, |
|
// as the numbers came into the server |
|
// |
|
// Parses buffer into fields and puts results into outbuf |
|
// size is size of the file read in |
|
//----------------------------------------------------------------------------- |
|
|
|
// 0=RIVA TNT |
|
// 1=GeForce2 MX |
|
// 2=Microsoft Corporation GDI Generic |
|
// 3=GeForce2 GTS |
|
// 4=Voodoo 3 |
|
// 5=Intel 810 |
|
// 6=GeForce3 |
|
|
|
#define CARDBINS 8 |
|
|
|
void TimeSeriesVCard( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
// unequally sized bins |
|
CUtlVector<int> nTimeList; |
|
int nQuantity[30][CARDBINS]; |
|
for (int i=0; i < 30; ++i) |
|
{ |
|
for (int j=0; j< CARDBINS; ++j) |
|
nQuantity[i][j]=0; |
|
} |
|
|
|
nTimeList.AddToTail(0); |
|
int bin=10000; |
|
int i=bin; |
|
for (i; i<=MAXUSERS; i=bin) |
|
{ |
|
nTimeList.AddToTail(i); |
|
bin<<=1; |
|
} |
|
nTimeList.AddToTail(i); |
|
|
|
//int currentTimeBin=1; |
|
|
|
// for unequal bins |
|
int currentTimeBin=1; |
|
int numTimeBins=nTimeList.Size(); |
|
|
|
int totalUsers=0; |
|
while ( (inbuf.TellGet() < size) ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
if (i >= 300) |
|
break; |
|
} |
|
// check for those blasted hackers |
|
if (i>= 300) |
|
{ |
|
// read rest |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
} |
|
continue; |
|
} |
|
|
|
pszCard[i] = '\0'; |
|
|
|
// 0=RIVA TNT |
|
// 1=GeForce2 MX |
|
// 2=Microsoft Corporation GDI Generic |
|
// 3=GeForce2 GTS |
|
// 4=Voodoo 3 |
|
// 5=Intel 810 |
|
// 6=GeForce3 |
|
// 7=All others |
|
int cardIndex=7; // default is other |
|
if ( Q_stristr ( pszCard, "RIVA TNT2" ) != NULL ) |
|
{ |
|
//printf ("%s", pszCard); |
|
cardIndex=0; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce2 MX" ) != NULL ) |
|
{ |
|
cardIndex=1; |
|
} |
|
else if ( Q_stristr ( pszCard, "Microsoft Corporation GDI Generic" ) != NULL ) |
|
{ |
|
cardIndex=2; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce2 GTS" ) != NULL ) |
|
{ |
|
cardIndex=3; |
|
} |
|
|
|
else if ( Q_stristr ( pszCard, "Voodoo3" ) != NULL ) |
|
{ |
|
cardIndex=4; |
|
} |
|
|
|
else if ( Q_stristr ( pszCard, "Intel 810" ) != NULL ) |
|
{ |
|
cardIndex=5; |
|
} |
|
|
|
else if ( Q_stristr ( pszCard, "GeForce3" ) != NULL ) |
|
{ |
|
cardIndex=6; |
|
} |
|
|
|
// update nTimeList bin if necessary |
|
if (nTimeList[currentTimeBin] <= totalUsers) |
|
{ |
|
currentTimeBin++; |
|
} |
|
|
|
nQuantity[currentTimeBin][cardIndex]++; |
|
|
|
totalUsers++; |
|
} |
|
|
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "Video Card" ); // headers |
|
for (int j=1; j < nTimeList.Size(); ++j) |
|
outbuf.Printf ("\tUsersSoFar%d", nTimeList[j]); |
|
outbuf.Printf ("\n"); |
|
|
|
for (int i=0; i < CARDBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "-"); |
|
for (int j=1; j < numTimeBins; ++j) // use NTIMEBINS for equal sized bins |
|
outbuf.Printf ("\t%d", nQuantity[j][i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Increment the proper bin's counter |
|
//----------------------------------------------------------------------------- |
|
|
|
void InsertResult( int nCpu, CUtlVector<int> &nCpuList, CUtlVector<int> &nQuantity ) |
|
{ |
|
if (nCpu < 0) // handle corrupt data |
|
return; |
|
|
|
// handle outliers--bin is off the scale |
|
if ( nCpu > nCpuList[nCpuList.Size()-1] ) |
|
{ |
|
//nCpuList.AddToTail( nCpu ); |
|
//nQuantity.AddToTail( 1 ); |
|
return; |
|
} |
|
|
|
int i=0; |
|
while ( nCpu > nCpuList[i] ) |
|
{ |
|
++i; |
|
} |
|
nQuantity[i-1]++; |
|
} |
|
|
|
|
|
|
|
void HistogramVidCards( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
|
|
#define CARDHISTBINS 15 |
|
// unequally sized bins |
|
int nQuantity[CARDHISTBINS]; |
|
for (int j=0; j< CARDHISTBINS; ++j) |
|
nQuantity[j]=0; |
|
|
|
int totalUsers=0; |
|
while ( (inbuf.TellGet() < size) ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
if (i >= 300) |
|
break; |
|
} |
|
// check for those blasted hackers |
|
if (i>= 300) |
|
{ |
|
// read rest |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
} |
|
continue; |
|
} |
|
|
|
pszCard[i] = '\0'; |
|
|
|
// 0=RIVA TNT2 |
|
// 1=GeForce2 MX |
|
// 2=Microsoft Corporation GDI Generic |
|
// 3=GeForce2 GTS |
|
// 4=Voodoo 3 |
|
// 5=Intel 810 |
|
// 6=GeForce3 |
|
// 7=Riva TNT |
|
// 8=GeForce 256 |
|
// 9=Rage 128 |
|
// 10=S3 Savage4 |
|
// 11=SiS 630 |
|
// 12=Radeon DDR |
|
// 13=Rage 128 Pro |
|
// 14=All others |
|
|
|
int cardIndex=14; // default is other |
|
if ( Q_stristr ( pszCard, "RIVA TNT2" ) != NULL ) |
|
{ |
|
//printf ("%s", pszCard); |
|
cardIndex=0; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce2 MX" ) != NULL ) |
|
{ |
|
cardIndex=1; |
|
} |
|
else if ( Q_stristr ( pszCard, "Microsoft Corporation GDI Generic" ) != NULL ) |
|
{ |
|
cardIndex=2; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce2 GTS" ) != NULL ) |
|
{ |
|
cardIndex=3; |
|
} |
|
|
|
else if ( Q_stristr ( pszCard, "Voodoo3" ) != NULL ) |
|
{ |
|
cardIndex=4; |
|
} |
|
|
|
else if ( Q_stristr ( pszCard, "Intel 810" ) != NULL ) |
|
{ |
|
cardIndex=5; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce3" ) != NULL ) |
|
{ |
|
cardIndex=6; |
|
} |
|
else if ( Q_stristr ( pszCard, "Riva TNT" ) != NULL ) |
|
{ |
|
cardIndex=7; |
|
} |
|
else if ( Q_stristr ( pszCard, "GeForce 256" ) != NULL ) |
|
{ |
|
cardIndex=8; |
|
} |
|
else if ( Q_stristr ( pszCard, "Rage 128 Pro" ) != NULL ) |
|
{ |
|
cardIndex=13; |
|
} |
|
else if ( Q_stristr ( pszCard, "Rage 128" ) != NULL ) |
|
{ |
|
cardIndex=9; |
|
} |
|
else if ( Q_stristr ( pszCard, "S3 Savage4" ) != NULL ) |
|
{ |
|
cardIndex=10; |
|
} |
|
else if ( Q_stristr ( pszCard, "SiS 630" ) != NULL ) |
|
{ |
|
cardIndex=11; |
|
} |
|
else if ( Q_stristr ( pszCard, "Radeon DDR" ) != NULL ) |
|
{ |
|
cardIndex=12; |
|
} |
|
|
|
nQuantity[cardIndex]++; |
|
|
|
totalUsers++; |
|
} |
|
|
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "Video Card" ); // headers |
|
outbuf.Printf ("\tNumber of Users\n"); |
|
outbuf.Printf ("\n"); |
|
|
|
for ( int i=0; i < CARDHISTBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "-"); |
|
outbuf.Printf ("\t%d", nQuantity[i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
void HistogramNetSpeed( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
#define NETHISTBINS 9 |
|
// unequally sized bins |
|
int nQuantity[NETHISTBINS]; |
|
for (int j=0; j< NETHISTBINS; ++j) |
|
nQuantity[j]=0; |
|
|
|
CUtlVector<int> nNetList; |
|
nNetList.AddToTail(0); |
|
nNetList.AddToTail(28); |
|
nNetList.AddToTail(33); |
|
nNetList.AddToTail(56); |
|
nNetList.AddToTail(112); |
|
nNetList.AddToTail(256); |
|
nNetList.AddToTail(512); |
|
nNetList.AddToTail(1100); |
|
nNetList.AddToTail(2000); |
|
|
|
int totalUsers=0; |
|
while ( (inbuf.TellGet() < size) ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
if (i >= 300) |
|
break; |
|
} |
|
// check for those blasted hackers |
|
if (i>= 300) |
|
{ |
|
// read rest |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
} |
|
continue; |
|
} |
|
|
|
pszCard[i] = '\0'; |
|
|
|
if (nNetSpeed < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nNetSpeed > nNetList[nNetList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nNetSpeed > nNetList[i] ) |
|
{ |
|
++i; |
|
} |
|
int netIndex = i; |
|
nQuantity[netIndex]++; |
|
|
|
totalUsers++; |
|
} |
|
|
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "Network Speed" ); // headers |
|
for (int j=0; j < nNetList.Size()-1; ++j) |
|
outbuf.Printf ("\t%d-%d", nNetList[j], nNetList[j+1]); |
|
outbuf.Printf ("\n"); |
|
|
|
for ( int i=0; i < NETHISTBINS; ++i ) |
|
{ |
|
outbuf.Printf ( "-"); |
|
outbuf.Printf ("\t%d", nQuantity[i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
void HistogramRam( CUtlBuffer &inbuf, CUtlBuffer &outbuf, char *pszSearchString, int size, int binwidth) |
|
{ |
|
#define RAMHISTBINS 20 |
|
// unequally sized bins |
|
int nQuantity[RAMHISTBINS]; |
|
for (int j=0; j< RAMHISTBINS; ++j) |
|
nQuantity[j]=0; |
|
|
|
CUtlVector<int> nRamList; |
|
nRamList.AddToTail(0); |
|
int basemem=16; |
|
while ( basemem < 2050 ) |
|
{ |
|
nRamList.AddToTail(basemem); |
|
basemem<<=1; |
|
} |
|
|
|
int totalUsers=0; |
|
while ( (inbuf.TellGet() < size) ) |
|
{ |
|
// Now parse the utlbuffer |
|
// file has fields of version, netspeed, ram, cpu and card type |
|
char pszVersion[256]; |
|
int nNetSpeed, nRam, nCpu; |
|
inbuf.Scanf( "%s %d %d %d", pszVersion, &nNetSpeed, &nRam, &nCpu ); |
|
|
|
char pszCard[300]; |
|
char chSentinel = ' '; |
|
int i=0; |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
pszCard[i] = chSentinel; |
|
++i; |
|
if (i >= 300) |
|
break; |
|
} |
|
// check for those blasted hackers |
|
if (i>= 300) |
|
{ |
|
// read rest |
|
while (( chSentinel != '\n' )) |
|
{ |
|
chSentinel = inbuf.GetChar(); |
|
} |
|
continue; |
|
} |
|
|
|
pszCard[i] = '\0'; |
|
|
|
if (nRam < 0) // handle corrupt data |
|
continue; |
|
// handle outliers--bin is off the scale |
|
if ( nRam > nRamList[nRamList.Size()-1] ) |
|
continue; |
|
i=0; |
|
while ( nRam > nRamList[i] ) |
|
{ |
|
++i; |
|
} |
|
int ramIndex = i; |
|
nQuantity[ramIndex]++; |
|
|
|
totalUsers++; |
|
} |
|
|
|
printf("TotalUsers %d\n", totalUsers); |
|
|
|
// write results to an output buffer |
|
outbuf.Printf ( "RAM" ); // headers |
|
for (int j=0; j < nRamList.Size()-1; ++j) |
|
outbuf.Printf ("\t%d-%d", nRamList[j], nRamList[j+1]); |
|
outbuf.Printf ("\n"); |
|
|
|
for ( int i=0; i < nRamList.Size(); ++i ) |
|
{ |
|
outbuf.Printf ( "-"); |
|
outbuf.Printf ("\t%d", nQuantity[i]); |
|
outbuf.Printf ("\n"); |
|
} |
|
} |
|
|
|
|
|
|
|
|