Skip to content

Instantly share code, notes, and snippets.

@iwazer
Created September 1, 2011 06:59
Show Gist options
  • Save iwazer/1185615 to your computer and use it in GitHub Desktop.
Save iwazer/1185615 to your computer and use it in GitHub Desktop.
分割されたApacheのログをマージする(C版)。This program merge divided Apache log.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits.h>
typedef struct preread {
FILE* file;
char *line_buf;
int dt;
} t_preread;
char* month_str[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
int MAX_OF_LINE_LEN = 8192;
int MONTH_NUM = -1;
int process(int sz, t_preread* prs[], int pickup);
int is_left(int sz, t_preread* prs[]);
int parse_dt(const char* line);
int get_min(int sz, t_preread* prs[]);
int month_num(char* s);
int main(int argc, char** argv) {
int sz = argc - 1;
t_preread* prereads[sz];
for (int i=0; i<sz; i++) {
prereads[i] = (t_preread *)malloc(sizeof(t_preread));
prereads[i]->file = fopen(argv[i+1], "r");
prereads[i]->line_buf = malloc(sizeof(char*)*MAX_OF_LINE_LEN);
if (NULL == fgets(prereads[i]->line_buf, MAX_OF_LINE_LEN, prereads[i]->file)) {
prereads[i]->line_buf[0] = 0;
prereads[i]->file = NULL;
break;
}
prereads[i]->dt = parse_dt(prereads[i]->line_buf);
prereads[i]->dt = 0;
}
int pickup = 0;
do {
pickup = process(sz, prereads, pickup);
} while (is_left(sz, prereads));
return 0;
}
int process(int sz, t_preread* prs[], int pickup) {
t_preread* pr = prs[pickup];
if (NULL != pr && 0 == pr->line_buf[0]) {
int dt = -1;
do {
if (NULL == fgets(pr->line_buf, MAX_OF_LINE_LEN, pr->file)) {
pr->line_buf[0] = 0;
pr->file = NULL;
break;
}
dt = parse_dt(pr->line_buf);
} while (dt < 0);
pr->dt = dt;
}
int min_idx = get_min(sz, prs);
t_preread* min_pr = prs[min_idx];
printf("%s", min_pr->line_buf);
min_pr->line_buf[0] = 0;
if (NULL == min_pr->file) {
prs[min_idx] = NULL;
return 0;
}
return min_idx;
}
int is_left(int sz, t_preread* prs[]) {
for (int i=0; i<sz; i++) {
if (NULL != prs[i]) return 1;
}
return 0;
}
int get_min(int sz, t_preread* prs[]) {
int min = INT_MAX;
int idx = 0;
for (int i=0; i<sz; i++) {
if (NULL == prs[i]) continue;
if (min > prs[i]->dt) {
min = prs[i]->dt;
idx = i;
}
}
return idx;
}
int find_dt_parts(char** p, int idx) {
char buf[5];
int i = 0;
for (i=0; i<4; i++) {
if (!isalnum(**p)) break;
buf[i] = **p;
(*p)++;
}
(*p)++;
buf[i] = 0;
if ('0' <= buf[0] && buf[0] <= '9') {
return atoi(buf);
} else {
if (MONTH_NUM < 0) MONTH_NUM = month_num(buf);
return MONTH_NUM;
}
return -1;
}
int month_num(char* s) {
for (int j=0; j<12; j++) {
if (0 == memcmp(s, month_str[j], 3)) {
return j;
}
}
return -1;
}
int parse_dt(const char* line) {
char* st = strchr(line, '[');
char* ed = strchr(line, ' ');
if (NULL == st || NULL == ed) return -1;
char* c = NULL;
int dt = 0;
st++;
int d = atoi(st); st += 3;
if (MONTH_NUM < 0) MONTH_NUM = month_num(st); //インチキだけど、ちょっとでも速く…
int m = MONTH_NUM; st += 4;
int y = atoi(st)-2000; st += 5;
int h = atoi(st); st += 3;
int M = atoi(st); st += 3;
int s = atoi(st);
return (y*365 + m*31 + d)*86400 + h*3600 + M*60 + s;
}
@iwazer
Copy link
Author

iwazer commented Sep 1, 2011

10mの処理が7mと若干早くなるだけ(-ω-)
書きなおした意味ね〜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment