// test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <unordered_map>
#else
#include <hash_map>
#endif
#include <stdio.h>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <chrono>
#include <iostream>
#ifdef WIN32
std::unordered_map<std::string, int> g_ipMap;
#else
std::hash_map<std::string, int> g_ipMap;
#endif
bool isVaildIp(const char* ip) {
if (ip == nullptr || *ip == '.') {
return false;
}
int dotsNum = 0;
int num = 0;
while (*ip) {
if (*ip == '.') {
dotsNum++;
if (num < 0 || num>255) {
return false;
}
num = 0;
ip++;
continue;
}
if (*ip < '0' || *ip>'9') {
return false;
}
num = num * 10 + (*ip - '0');
ip++;
}
if (num >= 0 && num <= 255 && dotsNum == 3) {
return true;
}
return false;
}
void addNumByIp(std::string ip){
auto rs = g_ipMap.find(ip);
if (rs != g_ipMap.end()) {
rs->second++;
}
else {
g_ipMap[ip] = 1;
}
}
void readFile(const char* name, char** buf, int& rdLen){
std::shared_ptr<FILE> pf(fopen(name, "r"), [](FILE* f) {
if (f) {
fclose(f);
}
}
);
if (pf == nullptr) {
return;
}
fseek(pf.get(), 0, SEEK_END);
rdLen = ftell(pf.get());
fseek(pf.get(), 0, SEEK_SET);
*buf = new char[rdLen + 1];
fread(*buf, 1, rdLen, pf.get());
(*buf)[rdLen] = '\0';
}
void writeResult(const char* name) {
std::shared_ptr<FILE> pf(fopen(name, "w"), [](FILE* f) {
if (f) {
fclose(f);
}
}
);
if (pf == nullptr) {
return;
}
int all = 0;
std::vector < std::pair<std::string, int>> v(g_ipMap.size());
int i = 0;
for (auto& rs : g_ipMap) {
v[i++] = make_pair(rs.first, rs.second);
all += rs.second;
}
std::sort(v.begin(), v.end(), [=](std::pair<std::string, int> a, std::pair<std::string, int> b) {
return a.second < b.second;
});
for (auto& i : v) {
fprintf(pf.get(), "%s %d\n", i.first.c_str(), i.second);
}
all++;
}
int testOld(){
auto t1 = std::chrono::system_clock::now();
char* buf = nullptr;
int rdLen;
readFile("access_log_2019-02-16.log", &buf, rdLen);
char* tmp = buf;
char* tmp2 = nullptr;
char* tmp3 = nullptr;
while (tmp) {
tmp2 = strstr(tmp, " - - ");
if (tmp2 == nullptr) {
break;
}
tmp2[0] = '\0';
if (isVaildIp(tmp)) {
addNumByIp(tmp);
}
if (tmp2[1] == '\0') {
break;
}
tmp = strstr(tmp2 + 1, "\n");
if (tmp) {
tmp++;
}
}
delete[] buf;
writeResult("resultOld.txt");
auto t2 = std::chrono::system_clock::now();
auto duration_1_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1.time_since_epoch());
auto duration_2_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2.time_since_epoch());
std::cout << "旧方法耗时" << duration_2_ms.count() - duration_1_ms.count() << std::endl;
return 0;
}