#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
#define MIN(X,Y) ((X<Y)?X:Y)
#define MAX(X,Y) ((X>Y)?X:Y)
class Client
{
friend class ClientList;
public:
Client(unsigned long theId);
unsigned long Id() {return id;}
unsigned long Sent() {return sent;}
void SetSent(unsigned long count) {sent = count;}
unsigned long Suppressed() {return suppressed;}
void SetSuppressed(unsigned long count) {suppressed = count;}
Client* Next() {return next;}
private:
unsigned long id;
unsigned long sent;
unsigned long suppressed;
Client* next;
};
class ClientList
{
public:
ClientList();
~ClientList();
void AddClient(Client* theClient);
void Destroy();
Client* FindClientById(unsigned long theId);
Client* Top() {return top;}
private:
Client* top;
};
Client::Client(unsigned long theId)
: id(theId), sent(0), suppressed(0), next(NULL)
{
}
ClientList::ClientList()
: top(NULL)
{
}
ClientList::~ClientList()
{
Destroy();
}
void ClientList::AddClient(Client* theClient)
{
theClient->next = top;
top = theClient;
}
void ClientList::Destroy()
{
while (top)
{
Client* next = top->next;
delete top;
top = next;
}
}
Client* ClientList::FindClientById(unsigned long theId)
{
Client* next = top;
while(next)
{
if (theId == next->id)
return next;
else
next = next->next;
}
return NULL;
}
const int MAX_LINE = 256;
class FastReader
{
public:
FastReader();
bool Read(FILE* filePtr, char* buffer, unsigned int* len);
bool Readline(FILE* filePtr, char* buffer, unsigned int* len);
private:
char savebuf[256];
char* saveptr;
unsigned int savecount;
};
FastReader::FastReader()
: savecount(0)
{
}
bool FastReader::Read(FILE* filePtr, char* buffer, unsigned int* len)
{
unsigned int want = *len;
if (savecount)
{
unsigned int ncopy = MIN(want, savecount);
memcpy(buffer, saveptr, ncopy);
savecount -= ncopy;
saveptr += ncopy;
buffer += ncopy;
want -= ncopy;
}
while (want)
{
unsigned int result = fread(savebuf, sizeof(char), 256, filePtr);
if (result)
{
unsigned int ncopy= MIN(want, result);
memcpy(buffer, savebuf, ncopy);
savecount = result - ncopy;
saveptr = savebuf + ncopy;
buffer += ncopy;
want -= ncopy;
}
else {
*len -= want;
if (*len)
return true; else
return false; }
}
return true;
}
bool FastReader::Readline(FILE* filePtr, char* buffer, unsigned int* len)
{
unsigned int count = 0;
unsigned int length = *len;
char* ptr = buffer;
unsigned int one = 1;
while ((count < length) && Read(filePtr, ptr, &one))
{
if (('\n' == *ptr) || ('\r' == *ptr))
{
*ptr = '\0';
*len = count;
return true;
}
count++;
ptr++;
}
if (count < length) *len = 0; return false;
}
int main(int argc, char* argv[])
{
ClientList list;
FastReader reader;
char buffer[512];
unsigned long line = 0;
unsigned int len = 512;
while (reader.Readline(stdin, buffer, &len))
{
line++;
if (!strncmp(buffer, "Report", 6))
{
char* ptr = strstr(buffer, "node>");
if (!ptr) break;
unsigned long nodeId;
if (1 != sscanf(ptr, "node>%lu", &nodeId))
{
fprintf(stderr, "nackCount: Error parsing log file "
"at line: %lu\n", line);
exit(-1);
}
len = 512;
while (reader.Readline(stdin, buffer, &len))
{
line++;
if ('*' == buffer[0]) break; len = 512;
ptr = strstr(buffer, "nacks>");
if (ptr)
{
Client* client = list.FindClientById(nodeId);
if (!client)
{
if (!(client = new Client(nodeId)))
{
perror("nackCount: Error creating Client:");
exit(-1);
}
list.AddClient(client);
}
unsigned long count;
if (1 == sscanf(ptr, "nacks>%lu", &count))
{
client->SetSent(count);
}
else
{
fprintf(stderr, "Error parsing log file "
"at line: %lu \n", line);
exit(-1);
}
if ((ptr = strstr(buffer, "suppressed>")))
{
if (1 == sscanf(ptr, "suppressed>%lu", &count))
{
client->SetSuppressed(count);
break;
}
}
else
{
fprintf(stderr, "Error parsing log file "
"at line: %lu \n", line);
exit(-1);
}
}
} }
len = 512;
}
unsigned long numClient = 0;
Client* next = list.Top();
unsigned long totalSent = 0;
unsigned long totalSuppressed = 0;
while (next)
{
totalSent += next->Sent();
totalSuppressed += next->Suppressed();
next = next->Next();
numClient++;
}
fprintf(stdout, "Receivers:%lu Sent:%lu Suppressed:%lu alpha:%f\n",
numClient, totalSent, totalSuppressed,
(double)totalSent / (double) (totalSuppressed+totalSent));
}