Last active
December 16, 2015 11:18
-
-
Save timglabisch/5425906 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<stdlib.h> | |
#include<string.h> | |
#include<assert.h> | |
#include<stdio.h> | |
#include<time.h> | |
#include<fcntl.h> | |
#define FILE_READ_BUFFER 16384 | |
#define FILE_WITE_BUFFER 16384 | |
// + ein Zeichen für das , | |
#define MAX_JSON_KEY_LEN 18 | |
#define MAX_JSON_VALUE_LEN 243 | |
#define MAX_SERVER_NAME_LEN 35 | |
#define try_next(where) if(*++c) { goto where; } else { c = c_start; memset(c, 0, FILE_READ_BUFFER); if(read(fIn, c, FILE_READ_BUFFER) < 1) { break; } else { goto where; } } | |
#define DEBUG false | |
struct timespec timeDiff(struct timespec start, struct timespec end) | |
{ | |
struct timespec result; | |
if (end.tv_nsec < start.tv_nsec){ // peform carry like in normal subtraction | |
// 123456789 | |
result.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; | |
result.tv_sec = end.tv_sec - 1 - start.tv_sec; | |
} | |
else{ | |
result.tv_nsec = end.tv_nsec - start.tv_nsec; | |
result.tv_sec = end.tv_sec - start.tv_sec; | |
} | |
return result; | |
} | |
int setNonblocking(int fd) | |
{ | |
int flags; | |
/* If they have O_NONBLOCK, use the Posix way to do it */ | |
#if defined(O_NONBLOCK) | |
/* Fixme: O_NONBLOCK is defined but broken on SunOS 4.1.x and AIX 3.2.5. */ | |
if (-1 == (flags = fcntl(fd, F_GETFL, 0))) | |
flags = 0; | |
return fcntl(fd, F_SETFL, flags | O_NONBLOCK); | |
#else | |
/* Otherwise, use the old way of doing it */ | |
flags = 1; | |
return ioctl(fd, FIOBIO, &flags); | |
#endif | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
printf("%d File Read Buffer \n%d File Write Buffer\n", FILE_READ_BUFFER, FILE_WITE_BUFFER); | |
// for benchmark | |
register unsigned int linecount = 0; | |
struct timespec start, end; | |
clock_gettime(CLOCK_MONOTONIC, &start); | |
assert(argc == 3); | |
int fIn = open((const char *)argv[1], O_RDONLY); | |
FILE *fOut = fopen(argv[2], "w+"); | |
setvbuf(fOut, NULL, _IOFBF, FILE_WITE_BUFFER); // scheint leider nichts zu bringen ... | |
setNonblocking(fileno(fOut)); | |
char jsonKeyBuffer[MAX_JSON_KEY_LEN]; | |
register char jsonKeyBufferPosition = 0; | |
char jsonValueBuffer[MAX_JSON_VALUE_LEN]; | |
register char jsonValueBufferPosition = 0; | |
char serverNameBuffer[MAX_SERVER_NAME_LEN]; | |
register char serverNameBufferPosition = 0; | |
memset(&jsonValueBuffer, 0, sizeof(char) * MAX_JSON_VALUE_LEN); | |
memset(&jsonKeyBuffer, 0, sizeof(char) * MAX_JSON_KEY_LEN); | |
memset(&serverNameBuffer, 0, sizeof(char) * MAX_SERVER_NAME_LEN); | |
// grenzwerte | |
register unsigned char POSITION_MAX_JSON_KEY = MAX_JSON_KEY_LEN - 1; | |
register unsigned char POSITION_MAX_JSON_VALUE = MAX_JSON_VALUE_LEN - 1; | |
register unsigned char POSITION_MAX_SERVER_NAME = MAX_SERVER_NAME_LEN - 1; | |
register char* c = (char*)malloc(sizeof(char) * FILE_READ_BUFFER); | |
char* c_start = c; | |
while(read(fIn, c, FILE_READ_BUFFER) > 0) { | |
//while(*c) { | |
POSITION_SERVERNAME: | |
if(*c == ' ') { | |
serverNameBuffer[serverNameBufferPosition++] = ','; | |
fwrite(serverNameBuffer, sizeof(char), serverNameBufferPosition, fOut); | |
serverNameBufferPosition = 0; | |
try_next(POSITION_BEFORE_KEY); | |
} | |
if(serverNameBufferPosition < POSITION_MAX_SERVER_NAME) { | |
serverNameBuffer[serverNameBufferPosition++] = *c; | |
} | |
try_next(POSITION_SERVERNAME); | |
POSITION_BEFORE_KEY: | |
if(*c == '"' || *c == '\'') { | |
try_next(POSITION_IN_KEY); | |
} | |
if(*c == '\n') { | |
fwrite(c, sizeof(char), 1, fOut); | |
memset(&serverNameBuffer, 0, sizeof(char) * MAX_SERVER_NAME_LEN); | |
++linecount; | |
try_next(POSITION_SERVERNAME); | |
} | |
try_next(POSITION_BEFORE_KEY); | |
POSITION_IN_KEY: | |
if(*c == '"' || *c == '\'') { | |
try_next(POSITION_BEFORE_VALUE); | |
} else { | |
if(jsonKeyBufferPosition < POSITION_MAX_JSON_KEY) { | |
jsonKeyBuffer[jsonKeyBufferPosition++] = *c; | |
} | |
} | |
try_next(POSITION_IN_KEY); | |
POSITION_BEFORE_VALUE: | |
if(*c == '"') { | |
try_next(POSITION_IN_STRING_QUESTIONMARK_VALUE); | |
} else if (*c == '\'') { | |
try_next(POSITION_IN_STRING_SINGLEQUESTIONMARK_VALUE); | |
} else if(*c >= '0' && *c <= '9') { | |
goto POSITION_IN_INT_VALUE; | |
} | |
try_next(POSITION_BEFORE_VALUE); | |
POSITION_IN_STRING_QUESTIONMARK_VALUE: | |
do { | |
do { | |
if(*c == '"') { | |
goto POSITION_HAS_RESULT; | |
} | |
if(jsonValueBufferPosition < POSITION_MAX_JSON_VALUE) { | |
jsonValueBuffer[jsonValueBufferPosition++] = *c; | |
} | |
} while(*++c); | |
c = c_start; | |
memset(c, 0, FILE_READ_BUFFER); // think this is a performance killer but ... | |
} while(read(fIn, c, FILE_READ_BUFFER) > 0); | |
goto POSITION_HAS_RESULT; | |
POSITION_IN_STRING_SINGLEQUESTIONMARK_VALUE: | |
do { | |
do { | |
if(*c == '\'') { | |
goto POSITION_HAS_RESULT; | |
} | |
if(jsonValueBufferPosition < POSITION_MAX_JSON_VALUE) { | |
jsonValueBuffer[jsonValueBufferPosition++] = *c; | |
} | |
} while(*++c); | |
c = c_start; | |
memset(c, 0, FILE_READ_BUFFER); // think this is a performance killer but ... | |
} while(read(fIn, c, FILE_READ_BUFFER) > 0); | |
goto POSITION_HAS_RESULT; | |
POSITION_IN_INT_VALUE: | |
if(*c >= '0' && *c <= '9' || *c == '.') { | |
if(jsonValueBufferPosition < POSITION_MAX_JSON_VALUE) { | |
jsonValueBuffer[jsonValueBufferPosition++] = *c; | |
} | |
try_next(POSITION_IN_INT_VALUE); | |
} | |
goto POSITION_HAS_RESULT; | |
POSITION_HAS_RESULT: | |
//printf("server: %s, key: %s, value: %s \n", serverNameBuffer, jsonKeyBuffer, jsonValueBuffer); | |
jsonValueBuffer[jsonValueBufferPosition++] = ','; | |
fwrite(jsonValueBuffer, sizeof(char), jsonValueBufferPosition, fOut); | |
jsonKeyBufferPosition = 0; | |
jsonValueBufferPosition = 0; | |
//memset(&jsonKeyBuffer, 0, sizeof(char) * MAX_JSON_KEY_LEN); | |
//memset(&jsonValueBuffer, 0, sizeof(char) * MAX_JSON_VALUE_LEN); | |
try_next(POSITION_BEFORE_KEY); | |
//} | |
//c = c_start; | |
} | |
clock_gettime(CLOCK_MONOTONIC, &end); | |
struct timespec timetaken = timeDiff(start, end); | |
float timetaken_in_ms = ((long long)timetaken.tv_sec * 1000) + (timetaken.tv_nsec / 1000000); | |
if (linecount > 0) { | |
long long performance = linecount / (timetaken_in_ms / 1000); | |
printf("time in ms %f\n", timetaken_in_ms); | |
printf("Lines: %d\n", linecount); | |
printf("Performance %lld lines/s\n", performance); | |
} | |
// muss nicht gemessen werden da dies völlig optional ist | |
// das os würde den Speicher so oder so feigeben :) | |
free(c); | |
close(fIn); | |
fclose(fOut); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment