summaryrefslogtreecommitdiff
path: root/utils/videocardstats/cardstats.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/videocardstats/cardstats.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/videocardstats/cardstats.cpp')
-rw-r--r--utils/videocardstats/cardstats.cpp1046
1 files changed, 1046 insertions, 0 deletions
diff --git a/utils/videocardstats/cardstats.cpp b/utils/videocardstats/cardstats.cpp
new file mode 100644
index 0000000..be15a65
--- /dev/null
+++ b/utils/videocardstats/cardstats.cpp
@@ -0,0 +1,1046 @@
+//========= 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");
+ }
+}
+
+
+