From 34c410998ff6ba7cb839b3dbb5ec930c083c5849 Mon Sep 17 00:00:00 2001 From: lion Date: Tue, 28 Jun 2022 18:30:34 +0800 Subject: [PATCH] xdb searcher and search test program are ready --- binding/c/main.c | 102 +++++++++++++++++++++++++++++++++++++-- binding/c/xdb_searcher.c | 17 +++++-- binding/c/xdb_searcher.h | 3 ++ 3 files changed, 114 insertions(+), 8 deletions(-) diff --git a/binding/c/main.c b/binding/c/main.c index e362960..164e070 100644 --- a/binding/c/main.c +++ b/binding/c/main.c @@ -7,9 +7,23 @@ // @Date 2022/06/28 #include "stdio.h" -#include "stdlib.h" +#include "sys/time.h" #include "xdb_searcher.h" +//read a line from a command line. +static char *get_line(FILE *fp, char *__dst) { + register int c; + register char *cs; + + cs = __dst; + while ( ( c = getc( fp ) ) != EOF ) { + if ( c == '\n' ) break; + *cs++ = c; + } + *cs = '\0'; + + return ( c == EOF && cs == __dst ) ? NULL : __dst; +} void print_help(char *argv[]) { printf("ip2region xdb searcher\n"); @@ -20,9 +34,17 @@ void print_help(char *argv[]) { } void test_search(int argc, char *argv[]) { - int i, n; + int i, n, err; + + // for args parse char *r, key[33] = {'\0'}, val[256] = {'\0'}; char db_file[256] = {'\0'}, cache_policy[16] = {"vectorIndex"}; + + // for search + long s_time, c_time; + unsigned int ip; + char line[256] = {'\0'}, region[256] = {'\0'}; + for (i = 2; i < argc; i++) { r = argv[i]; if (strlen(r) < 5) { @@ -64,7 +86,81 @@ void test_search(int argc, char *argv[]) { return; } - printf("db_file=%s, cache_policy=%s\n", db_file, cache_policy); + // printf("db_file=%s, cache_policy=%s\n", db_file, cache_policy); + + xdb_searcher_t searcher; + char *vIndex = NULL, *cBuffer = NULL; + if (strcmp(cache_policy, "file") == 0) { + err = xdb_new_with_file_only(&searcher, db_file); + if (err != 0) { + printf("failed to create searcher with errcode=%d", err); + return; + } + } else if (strcmp(cache_policy, "vectorIndex") == 0) { + vIndex = xdb_load_vector_index_from_file(db_file); + if (vIndex == NULL) { + printf("failed to load vector index from `%s`", db_file); + return; + } + + err = xdb_new_with_vector_index(&searcher, db_file, vIndex); + if (err != 0) { + printf("failed to create vector index cached searcher with errcode=%d", err); + return; + } + } else if (strcmp(cache_policy, "content") == 0) { + cBuffer = xdb_load_content_from_file(db_file); + if (cBuffer == NULL) { + printf("failed to load xdb content from `%s`", db_file); + return; + } + + err = xdb_new_with_buffer(&searcher, cBuffer); + if (err != 0) { + printf("failed to create content cached searcher with errcode=%d", err); + return; + } + } else { + printf("invalid cache policy `%s`, options: file/vectorIndex/content", cache_policy); + return; + } + + printf("ip2region xdb searcher test program, " + "cache_policy: %s\ntype 'quit' to exit\n", cache_policy); + while ( 1 ) { + printf("ip2region>> "); + get_line(stdin, line); + if ( strlen(line) < 2 ) { + continue; + } + + if (strcasecmp( line, "quit") == 0 ) { + break; + } + + if (check_ip(line, &ip) != 0) { + printf("invalid ip address `%s`\n", line); + continue; + } + + s_time = xdb_now(); + err = xdb_search(&searcher, ip, region, sizeof(region)); + if (err != 0) { + printf("{err: %d, io_count: %d}\n", err, xdb_get_io_count(&searcher)); + } else { + c_time = xdb_now() - s_time; + printf("{region: %s, io_count: %d, took: %ld μs}\n", region, xdb_get_io_count(&searcher), c_time); + } + } + + xdb_close(&searcher); + if (vIndex != NULL) { + xdb_free(vIndex); + } + if(cBuffer != NULL) { + xdb_free(cBuffer); + } + printf("searcher test program exited, thanks for trying\n"); } void test_bench(int argc, char *argv[]) { diff --git a/binding/c/xdb_searcher.c b/binding/c/xdb_searcher.c index 5f77c51..f0718c3 100644 --- a/binding/c/xdb_searcher.c +++ b/binding/c/xdb_searcher.c @@ -6,6 +6,7 @@ // @Author Lion // @Date 2022/06/27 +#include "sys/time.h" #include "xdb_searcher.h" // internal function prototype define @@ -92,8 +93,7 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu e_ptr = get_unsigned_int(vector_buffer, 4); } - printf("s_ptr=%u, e_ptr=%u", s_ptr, e_ptr); - + // printf("s_ptr=%u, e_ptr=%u\n", s_ptr, e_ptr); // binary search to get the final region info data_len = 0, data_ptr = 0; l = 0, h = (e_ptr - s_ptr) / xdb_segment_index_size; @@ -117,13 +117,13 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu l = m + 1; } else { data_len = get_unsigned_short(segment_buffer, 8); - data_ptr = get_unsigned_short(segment_buffer, 10); + data_ptr = get_unsigned_int(segment_buffer, 10); break; } } } - printf("data_len=%u, data_ptr=%u\n", data_len, data_ptr); + // printf("data_len=%u, data_ptr=%u\n", data_len, data_ptr); if (data_len == 0) { region_buffer[0] = '\0'; return 0; @@ -156,7 +156,8 @@ XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t len return 1; } - if (fread(buffer, 1, length, xdb->handle) != -1) { + xdb->io_count++; + if (fread(buffer, 1, length, xdb->handle) != length) { return 2; } @@ -327,4 +328,10 @@ XDB_PUBLIC(int) check_ip(const char *src_ip, unsigned int *dst_ip) { // unsigned int ip to string ip XDB_PUBLIC(void) long2ip(unsigned int ip, char *buffer) { sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); +} + +XDB_PUBLIC(long) xdb_now() { + struct timeval c_time; + gettimeofday(&c_time, NULL); + return c_time.tv_sec * (int)1e6 + c_time.tv_usec; } \ No newline at end of file diff --git a/binding/c/xdb_searcher.h b/binding/c/xdb_searcher.h index a71ed2b..2ce0347 100644 --- a/binding/c/xdb_searcher.h +++ b/binding/c/xdb_searcher.h @@ -120,5 +120,8 @@ XDB_PUBLIC(int) check_ip(const char *, unsigned int *); // unsigned int ip to string ip XDB_PUBLIC(void) long2ip(unsigned int, char *); +// get the current time in microseconds +XDB_PUBLIC(long) xdb_now(); + #endif //C_XDB_SEARCHER_H