Skip to content

Instantly share code, notes, and snippets.

@timglabisch
Last active December 16, 2015 11:18
Show Gist options
  • Save timglabisch/5425906 to your computer and use it in GitHub Desktop.
Save timglabisch/5425906 to your computer and use it in GitHub Desktop.
#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