diff --git a/binding/c/main.c b/binding/c/main.c index 8a2219e..9270260 100644 --- a/binding/c/main.c +++ b/binding/c/main.c @@ -199,7 +199,7 @@ void test_bench(int argc, char *argv[]) { FILE *handle; char line[1024] = {'\0'}, sip_str[16] = {'\0'}, eip_str[16] = {'\0'}; char src_region[512] = {'\0'}, region_buffer[512] = {'\0'}; - unsigned int sip, eip, mip, ip_list[5]; + unsigned int sip, eip, ip_list[2]; int count = 0, took; long s_time, t_time, c_time = 0; searcher_test_t test; @@ -283,13 +283,9 @@ void test_bench(int argc, char *argv[]) { return; } - mip = xdb_mip(sip, eip); ip_list[0] = sip; - ip_list[1] = xdb_mip(sip, mip); - ip_list[2] = mip; - ip_list[3] = xdb_mip(mip, eip); - ip_list[4] = eip; - for (i = 0; i < 5; i++) { + ip_list[1] = eip; + for (i = 0; i < 2; i++) { t_time = xdb_now(); err = xdb_search(&test.searcher, ip_list[i], region_buffer, sizeof(region_buffer)); if (err != 0) { diff --git a/binding/c/test_util b/binding/c/test_util index 625cdc9..bc93a29 100755 Binary files a/binding/c/test_util and b/binding/c/test_util differ diff --git a/binding/c/xdb_api.h b/binding/c/xdb_api.h index 22b1d5e..21e28d3 100644 --- a/binding/c/xdb_api.h +++ b/binding/c/xdb_api.h @@ -37,8 +37,38 @@ // cache of vector_index_row × vector_index_rows × vector_index_size #define xdb_vector_index_length 524288 +// --- xdb util functions -// --- buffer load util functions +// get the current time in microseconds +XDB_PUBLIC(long) xdb_now(); + +// get unsigned long (4bytes) from a specified buffer start from the specified offset with little-endian +XDB_PUBLIC(unsigned int) xdb_le_get_uint32(const char *, int); + +// get unsigned short (2bytes) from a specified buffer start from the specified offset with little-endian +XDB_PUBLIC(int) xdb_le_get_uint16(const char *, int); + +// check the specified string ip and convert it to an unsigned int +XDB_PUBLIC(int) xdb_check_ip(const char *, unsigned int *); + +// unsigned int ip to string ip +XDB_PUBLIC(void) xdb_long2ip(unsigned int, char *); + + +// parse the specified IP address to byte array +XDB_PUBLIC(int) xdb_parse_ip(const char *, const char *, size_t); + +// convert a specified ip bytes to humen-readable string +XDB_PUBLIC(int) xdb_ip_to_string(const char *, size_t); + +// compare the specified ip bytes with another ip bytes in the specified buff from offset. +// returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0 +XDB_PUBLIC(int) xdb_ip_sub_compare(const char *, const char *, int, size_t); + +// --- END xdb utils + + +// --- xdb buffer functions // use the following buffer struct to wrap the binary buffer data // since the buffer data could not be operated with the string API. @@ -48,6 +78,10 @@ struct xdb_header { unsigned int created_at; unsigned int start_index_ptr; unsigned int end_index_ptr; + + // since 3.0+ with IPv6 supporting + unsigned short ip_version; + unsigned short runtime_ptr_bytes; // the original buffer unsigned int length; @@ -89,7 +123,9 @@ XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *); XDB_PUBLIC(void) xdb_free_content(void *); -// --- End buffer load +// --- End xdb buffer + +// --- xdb searcher api // xdb searcher structure struct xdb_searcher_entry { @@ -126,24 +162,6 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *, unsigned int, char *, size_t); XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *); - -// get unsigned long (4bytes) from a specified buffer start from the specified offset with little-endian -XDB_PUBLIC(unsigned int) xdb_get_uint(const char *, int); - -// get unsigned short (2bytes) from a specified buffer start from the specified offset with little-endian -XDB_PUBLIC(int) xdb_get_ushort(const char *, int); - -// check the specified string ip and convert it to an unsigned int -XDB_PUBLIC(int) xdb_check_ip(const char *, unsigned int *); - -// unsigned int ip to string ip -XDB_PUBLIC(void) xdb_long2ip(unsigned int, char *); - -// get the middle ip of a and b -XDB_PUBLIC(unsigned int) xdb_mip(unsigned long, unsigned long); - -// get the current time in microseconds -XDB_PUBLIC(long) xdb_now(); - +// --- END xdb searcher api #endif // C_IP2REGION_XDB_H diff --git a/binding/c/xdb_searcher.c b/binding/c/xdb_searcher.c index 7ad4d16..b372e87 100644 --- a/binding/c/xdb_searcher.c +++ b/binding/c/xdb_searcher.c @@ -79,19 +79,19 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu il1 = ((int) (ip >> 16)) & 0xFF; idx = il0 * xdb_vector_index_cols * xdb_vector_index_size + il1 * xdb_vector_index_size; if (xdb->v_index != NULL) { - s_ptr = xdb_get_uint(xdb->v_index->buffer, idx); - e_ptr = xdb_get_uint(xdb->v_index->buffer, idx + 4); + s_ptr = xdb_le_get_uint32(xdb->v_index->buffer, idx); + e_ptr = xdb_le_get_uint32(xdb->v_index->buffer, idx + 4); } else if (xdb->content != NULL) { - s_ptr = xdb_get_uint(xdb->content->buffer, xdb_header_info_length + idx); - e_ptr = xdb_get_uint(xdb->content->buffer, xdb_header_info_length + idx + 4); + s_ptr = xdb_le_get_uint32(xdb->content->buffer, xdb_header_info_length + idx); + e_ptr = xdb_le_get_uint32(xdb->content->buffer, xdb_header_info_length + idx + 4); } else { err = read(xdb, xdb_header_info_length + idx, vector_buffer, sizeof(vector_buffer)); if (err != 0) { return 10 + err; } - s_ptr = xdb_get_uint(vector_buffer, 0); - e_ptr = xdb_get_uint(vector_buffer, 4); + s_ptr = xdb_le_get_uint32(vector_buffer, 0); + e_ptr = xdb_le_get_uint32(vector_buffer, 4); } // printf("s_ptr=%u, e_ptr=%u\n", s_ptr, e_ptr); @@ -109,16 +109,16 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu } // decode the data fields as needed - sip = xdb_get_uint(segment_buffer, 0); + sip = xdb_le_get_uint32(segment_buffer, 0); if (ip < sip) { h = m - 1; } else { - eip = xdb_get_uint(segment_buffer, 4); + eip = xdb_le_get_uint32(segment_buffer, 4); if (ip > eip) { l = m + 1; } else { - data_len = xdb_get_ushort(segment_buffer, 8); - data_ptr = xdb_get_uint(segment_buffer, 10); + data_len = xdb_le_get_uint16(segment_buffer, 8); + data_ptr = xdb_le_get_uint32(segment_buffer, 10); break; } } diff --git a/binding/c/xdb_util.c b/binding/c/xdb_util.c index 2d6c9e9..2c0f034 100644 --- a/binding/c/xdb_util.c +++ b/binding/c/xdb_util.c @@ -35,6 +35,82 @@ XDB_PRIVATE(int) gettimeofday(struct timeval* tp, void* tzp) { } #endif +XDB_PUBLIC(long) xdb_now() { + struct timeval c_time; + gettimeofday(&c_time, NULL); + return c_time.tv_sec * (int)1e6 + c_time.tv_usec; +} + +XDB_PUBLIC(unsigned int) xdb_le_get_uint32(const char *buffer, int offset) { + return ( + ((buffer[offset ]) & 0x000000FF) | + ((buffer[offset+1] << 8) & 0x0000FF00) | + ((buffer[offset+2] << 16) & 0x00FF0000) | + ((buffer[offset+3] << 24) & 0xFF000000) + ); +} + +XDB_PUBLIC(int) xdb_le_get_uint16(const char *buffer, int offset) { + return ( + ((buffer[offset ]) & 0x000000FF) | + ((buffer[offset+1] << 8) & 0x0000FF00) + ); +} + +// string ip to unsigned int +static int shiftIndex[4] = {24, 16, 8, 0}; +XDB_PUBLIC(int) xdb_check_ip(const char *src_ip, unsigned int *dst_ip) { + char c; + int i, n, ip = 0; + const char *ptr = src_ip; + for (i = 0; i < 4; i++) { + n = 0; + while (1) { + c = *ptr; + ptr++; + if (c >= '0' && c <= '9') { + n *= 10; + n += c - '0'; + } else if ((i < 3 && c == '.') || i == 3) { + // stopping at the '.' but ignore the tailing chars + // after the 3rd one (auto clean the tailing none-integer ?). + break; + } else { + return 1; + } + } + + if (n > 0xFF) { + return 2; + } + + ip |= (n << shiftIndex[i]); + } + + *dst_ip = ip; + return 0; +} + +// unsigned int ip to string ip +XDB_PUBLIC(void) xdb_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(int) xdb_parse_ip(const char *ip, const char *buffer, size_t length) { + return 0; +} + +XDB_PUBLIC(int) xdb_ip_to_string(const char *bytes, size_t length) { + return 0; +} + +XDB_PUBLIC(int) xdb_ip_sub_compare(const char *ip1, const char *buffer, int offset, size_t length) { + return 0; +} + + +// --- xdb buffer function implementations + XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *handle) { xdb_header_t *header; unsigned int size = xdb_header_info_length; @@ -57,11 +133,15 @@ XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *handle) { // fill the fields header->length = size; - header->version = (unsigned short) xdb_get_ushort(header->buffer, 0); - header->index_policy = (unsigned short) xdb_get_ushort(header->buffer, 2); - header->created_at = xdb_get_uint(header->buffer, 4); - header->start_index_ptr = xdb_get_uint(header->buffer, 8); - header->end_index_ptr = xdb_get_uint(header->buffer,12); + header->version = (unsigned short) xdb_le_get_uint16(header->buffer, 0); + header->index_policy = (unsigned short) xdb_le_get_uint16(header->buffer, 2); + header->created_at = xdb_le_get_uint32(header->buffer, 4); + header->start_index_ptr = xdb_le_get_uint32(header->buffer, 8); + header->end_index_ptr = xdb_le_get_uint32(header->buffer,12); + + // since IPv6 supporting + header->ip_version = xdb_le_get_uint16(header->buffer, 16); + header->runtime_ptr_bytes = xdb_le_get_uint16(header->buffer, 18); return header; } @@ -194,71 +274,3 @@ XDB_PUBLIC(void) xdb_free_content(void *ptr) { } // --- End - -// get unsigned long (4bytes) from a specified buffer start from the specified offset -XDB_PUBLIC(unsigned int) xdb_get_uint(const char *buffer, int offset) { - return ( - ((buffer[offset ]) & 0x000000FF) | - ((buffer[offset+1] << 8) & 0x0000FF00) | - ((buffer[offset+2] << 16) & 0x00FF0000) | - ((buffer[offset+3] << 24) & 0xFF000000) - ); -} - -// get unsigned short (2bytes) from a specified buffer start from the specified offset -XDB_PUBLIC(int) xdb_get_ushort(const char *buffer, int offset) { - return ( - ((buffer[offset ]) & 0x000000FF) | - ((buffer[offset+1] << 8) & 0x0000FF00) - ); -} - -// string ip to unsigned int -static int shiftIndex[4] = {24, 16, 8, 0}; -XDB_PUBLIC(int) xdb_check_ip(const char *src_ip, unsigned int *dst_ip) { - char c; - int i, n, ip = 0; - const char *ptr = src_ip; - for (i = 0; i < 4; i++) { - n = 0; - while (1) { - c = *ptr; - ptr++; - if (c >= '0' && c <= '9') { - n *= 10; - n += c - '0'; - } else if ((i < 3 && c == '.') || i == 3) { - // stopping at the '.' but ignore the tailing chars - // after the 3rd one (auto clean the tailing none-integer ?). - break; - } else { - return 1; - } - } - - if (n > 0xFF) { - return 2; - } - - ip |= (n << shiftIndex[i]); - } - - *dst_ip = ip; - return 0; -} - -// unsigned int ip to string ip -XDB_PUBLIC(void) xdb_long2ip(unsigned int ip, char *buffer) { - sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); -} - -// get the middle ip of a and b -XDB_PUBLIC(unsigned int) xdb_mip(unsigned long a, unsigned long b) { - return (unsigned int) ((a + b) >> 1); -} - -XDB_PUBLIC(long) xdb_now() { - struct timeval c_time; - gettimeofday(&c_time, NULL); - return c_time.tv_sec * (int)1e6 + c_time.tv_usec; -}