-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add binding maker and editor for C++
- Loading branch information
Showing
17 changed files
with
1,566 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
all: xdb_search xdb_bench | ||
|
||
xdb_search: xdb_search.cc xdb_search_test.cc | ||
g++ -std=c++11 -O2 $^ -o $@ | ||
|
||
xdb_bench: xdb_search.cc xdb_bench.cc xdb_bench_test.cc | ||
g++ -std=c++11 -O2 $^ -o $@ | ||
|
||
clean: | ||
rm -f xdb_search xdb_bench |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# ip2region xdb C++ 查询客户端实现 | ||
|
||
## 使用方式 | ||
### 完全基于文件的查询 | ||
``` | ||
#include <iostream> | ||
#include "xdb_search.h" | ||
int main(int argc, char* argv[]) { | ||
char file_name[] = "../../data/ip2region.xdb"; | ||
char ip[] = "1.2.3.4"; | ||
xdb_search_t xdb(file_name); | ||
xdb.init_file(); | ||
std::cout << xdb.search(ip) << std::endl; | ||
return 0; | ||
} | ||
``` | ||
|
||
### 缓存 `vector_index` 索引 | ||
``` | ||
#include <iostream> | ||
#include "xdb_search.h" | ||
int main(int argc, char* argv[]) { | ||
char file_name[] = "../../data/ip2region.xdb"; | ||
char ip[] = "1.2.3.4"; | ||
xdb_search_t xdb(file_name); | ||
xdb.init_vector_index(); | ||
std::cout << xdb.search(ip) << std::endl; | ||
return 0; | ||
} | ||
``` | ||
|
||
### 缓存整个 `xdb` 数据 | ||
``` | ||
#include <iostream> | ||
#include "xdb_search.h" | ||
int main(int argc, char* argv[]) { | ||
char file_name[] = "../../data/ip2region.xdb"; | ||
char ip[] = "1.2.3.4"; | ||
xdb_search_t xdb(file_name); | ||
xdb.init_content(); | ||
std::cout << xdb.search(ip) << std::endl; | ||
return 0; | ||
} | ||
``` | ||
|
||
## 测试程序编译 | ||
1. 切换到当前目录 | ||
2. 编译 | ||
|
||
``` | ||
$ make | ||
g++ -std=c++11 -O2 xdb_search.cc xdb_search_test.cc -o xdb_search | ||
g++ -std=c++11 -O2 xdb_search.cc xdb_bench.cc xdb_bench_test.cc -o xdb_bench | ||
``` | ||
|
||
## 测试查询 | ||
### 说明 | ||
``` | ||
$ ./xdb_search --help | ||
./xdb_search [command options] | ||
options: | ||
--db string ip2region binary xdb file path | ||
--cache-policy string cache policy: file/vector_index/content | ||
--help print help | ||
``` | ||
|
||
### 测试 | ||
``` | ||
$ ./xdb_search --db ../../data/ip2region.xdb --cache-policy vector_index | ||
cache policy : vector_index | ||
ip2region>> 1.2.3.4 | ||
美国|0|华盛顿|0|谷歌 | ||
``` | ||
|
||
## bench 测试 | ||
### 说明 | ||
``` | ||
$ ./xdb_bench --help | ||
./xdb_bench [command options] | ||
options: | ||
--db string ip2region binary xdb file path | ||
--src string source ip text file path | ||
--cache-policy string cache policy: file/vector_index/content | ||
--help print help | ||
``` | ||
|
||
### 测试 | ||
``` | ||
$ ./xdb_bench --db ../../data/ip2region.xdb --src ../../data/ip.merge.txt --cache-policy content | ||
total: 3419220, took: 3.44 s, cost: 0.27 μs/op, io count: 0 | ||
$ ./xdb_bench --db ../../data/ip2region.xdb --src ../../data/ip.merge.txt --cache-policy vector_index | ||
total: 3419220, took: 45.99 s, cost: 12.24 μs/op, io count: 21739300 | ||
$ ./xdb_bench --db ../../data/ip2region.xdb --src ../../data/ip.merge.txt --cache-policy file | ||
total: 3419220, took: 60.39 s, cost: 16.32 μs/op, io count: 25158520 | ||
``` | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
|
||
#include "xdb_bench.h" | ||
|
||
#include <arpa/inet.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <sys/time.h> | ||
|
||
#include <iostream> | ||
#include <vector> | ||
|
||
static void log_exit(const std::string &msg) { | ||
std::cout << msg << std::endl; | ||
exit(-1); | ||
} | ||
|
||
static unsigned long long get_time() { | ||
struct timeval tv1; | ||
gettimeofday(&tv1, NULL); | ||
return (unsigned long long)tv1.tv_sec * 1000 * 1000 + tv1.tv_usec; | ||
} | ||
|
||
static bool ip2uint(const char *buf, unsigned int &ip) { | ||
struct in_addr addr; | ||
if (inet_pton(AF_INET, buf, &addr) == 0) | ||
return false; | ||
// 网络字节序为大端存储, 在此转换为小端存储 | ||
ip = (((addr.s_addr >> 0) & 0xFF) << 24) | | ||
(((addr.s_addr >> 8) & 0xFF) << 16) | | ||
(((addr.s_addr >> 16) & 0xFF) << 8) | | ||
(((addr.s_addr >> 24) & 0xFF) << 0); | ||
return true; | ||
} | ||
|
||
static std::string uint2ip(unsigned int ip) { | ||
char buf[16]; | ||
snprintf(buf, | ||
sizeof(buf), | ||
"%d.%d.%d.%d", | ||
(ip >> 24) & 0xFF, | ||
(ip >> 16) & 0xFF, | ||
(ip >> 8) & 0xFF, | ||
ip & 0xFF); | ||
return std::string(buf); | ||
} | ||
|
||
xdb_bench_t::xdb_bench_t(const std::string &file_name) : xdb_search(file_name) { | ||
} | ||
|
||
void xdb_bench_t::init_file() { | ||
xdb_search.init_file(); | ||
} | ||
|
||
void xdb_bench_t::init_vector_index() { | ||
xdb_search.init_vector_index(); | ||
} | ||
|
||
void xdb_bench_t::init_content() { | ||
xdb_search.init_content(); | ||
} | ||
|
||
void xdb_bench_t::bench_test_one(unsigned int ip_uint, const char *region) { | ||
if (xdb_search.search(uint2ip(ip_uint)) != region) | ||
log_exit("failed: " + uint2ip(ip_uint)); | ||
sum_io_count += xdb_search.get_io_count(); | ||
sum_cost_time += xdb_search.get_cost_time(); | ||
sum_count++; | ||
} | ||
|
||
void xdb_bench_t::bench_test_line(char *buf) { | ||
size_t buf_len = strlen(buf); | ||
if (buf_len == 0) | ||
return; | ||
buf[buf_len - 1] = '\0'; // 去掉换行符 | ||
|
||
char *pos1 = strchr(buf, '|'); | ||
|
||
if (pos1 == NULL) | ||
log_exit("invalid data: " + std::string(buf)); | ||
char *pos2 = strchr(pos1 + 1, '|'); | ||
if (pos2 == NULL) | ||
log_exit("invalid data: " + std::string(buf)); | ||
*pos1 = '\0'; | ||
*pos2 = '\0'; | ||
|
||
unsigned int ip1, ip2; | ||
if (!ip2uint(buf, ip1) || !ip2uint(pos1 + 1, ip2) || ip1 > ip2) { | ||
*pos1 = *pos2 = '|'; | ||
log_exit(std::string("invalid data: ") + buf); | ||
} | ||
|
||
const char *region = pos2 + 1; | ||
|
||
unsigned int ip_mid = ip1 + (ip2 - ip1) / 2; | ||
std::vector<unsigned int> ip_vec; | ||
ip_vec.push_back(ip1); | ||
ip_vec.push_back(ip1 + (ip_mid - ip1) / 2); | ||
ip_vec.push_back(ip_mid); | ||
ip_vec.push_back(ip_mid + (ip2 - ip_mid) / 2); | ||
ip_vec.push_back(ip2); | ||
|
||
for (auto &d : ip_vec) | ||
bench_test_one(d, region); | ||
} | ||
|
||
void xdb_bench_t::bench_test_file(const std::string &file_name) { | ||
FILE *f = fopen(file_name.data(), "r"); | ||
if (f == NULL) | ||
log_exit("can't open " + file_name); | ||
char buf[1024]; | ||
while (fgets(buf, sizeof(buf), f) != NULL) | ||
bench_test_line(buf); | ||
} | ||
|
||
void xdb_bench_t::bench(const std::string &file_name) { | ||
sum_io_count = 0; | ||
sum_cost_time = 0; | ||
sum_count = 0; | ||
|
||
unsigned long long tv1 = get_time(); | ||
bench_test_file(file_name); | ||
unsigned long long tv2 = get_time(); | ||
|
||
double took = (tv2 - tv1) * 1.0 / 1000 / 1000; | ||
double cost = sum_cost_time * 1.0 / sum_count; | ||
|
||
printf( | ||
"total: %llu, took: %.2f s, cost: %.2f μs/op, io " | ||
"count: " | ||
"%llu\n", | ||
sum_count, | ||
took, | ||
cost, | ||
sum_io_count); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#ifndef XDB_BENCH_H | ||
#define XDB_BENCH_H | ||
|
||
#include "xdb_search.h" | ||
|
||
class xdb_bench_t { | ||
public: | ||
xdb_bench_t(const std::string &file_name); | ||
|
||
void init_file(); | ||
void init_vector_index(); | ||
void init_content(); | ||
|
||
void bench(const std::string &file_name); | ||
|
||
private: | ||
void bench_test_one(unsigned int ip_uint, const char *region); | ||
void bench_test_line(char *buf); | ||
void bench_test_file(const std::string &file_name); | ||
|
||
xdb_search_t xdb_search; | ||
|
||
unsigned long long sum_io_count; | ||
unsigned long long sum_cost_time; | ||
unsigned long long sum_count; | ||
}; | ||
|
||
#endif |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
|
||
#include "xdb_bench.h" | ||
|
||
#include <getopt.h> | ||
|
||
#include <iostream> | ||
|
||
void print_help(int argc, char* argv[]) { | ||
printf("./xdb_bench [command options]\n"); | ||
printf("options:\n"); | ||
printf(" --db string ip2region binary xdb file path\n"); | ||
printf(" --src string source ip text file path\n"); | ||
printf( | ||
" --cache-policy string cache policy: " | ||
"file/vector_index/content\n"); | ||
printf(" --help print help\n"); | ||
exit(-1); | ||
} | ||
|
||
int main(int argc, char* argv[]) { | ||
struct option long_options[] = { | ||
{"db", required_argument, 0, 'd'}, | ||
{"cache-policy", required_argument, 0, 't'}, | ||
{"src", required_argument, 0, 's'}, | ||
{"help", no_argument, 0, 'h'}, | ||
{0, 0, 0, 0 } | ||
}; | ||
|
||
std::string db_file_name = "../../data/ip2region.xdb"; | ||
std::string src_file_name = "../../data/ip.merge.txt"; | ||
std::string cache_policy = "vector_index"; | ||
|
||
while (1) { | ||
int c = getopt_long(argc, argv, "", long_options, NULL); | ||
if (c == -1) | ||
break; | ||
switch (c) { | ||
case 'd': | ||
db_file_name = optarg; | ||
break; | ||
case 'h': | ||
print_help(argc, argv); | ||
break; | ||
case 't': | ||
cache_policy = optarg; | ||
break; | ||
case 's': | ||
src_file_name = optarg; | ||
break; | ||
case '?': | ||
exit(-1); | ||
} | ||
} | ||
|
||
xdb_bench_t xdb(db_file_name); | ||
|
||
if (cache_policy == "content") | ||
xdb.init_content(); | ||
else if (cache_policy == "vector_index") | ||
xdb.init_vector_index(); | ||
else if (cache_policy == "file") | ||
xdb.init_file(); | ||
else { | ||
std::cout << "invalid cache policy: " << cache_policy << std::endl; | ||
exit(-1); | ||
} | ||
|
||
xdb.bench(src_file_name); | ||
return 0; | ||
} |
Oops, something went wrong.