提交 288859f7 编写于 作者: L Lion

wrap the header/vector/content buffer

上级 420bc3fb
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
struct searcher_test_entry { struct searcher_test_entry {
xdb_searcher_t searcher; xdb_searcher_t searcher;
char *v_index; xdb_vector_index_t *v_index;
char *c_buffer; xdb_content_t *c_buffer;
}; };
typedef struct searcher_test_entry searcher_test_t; typedef struct searcher_test_entry searcher_test_t;
...@@ -64,13 +64,13 @@ void destroy_searcher_test(searcher_test_t *test) { ...@@ -64,13 +64,13 @@ void destroy_searcher_test(searcher_test_t *test) {
// check and free the vector index // check and free the vector index
if (test->v_index != NULL) { if (test->v_index != NULL) {
xdb_free(test->v_index); xdb_close_vector_index(test->v_index);
test->v_index = NULL; test->v_index = NULL;
} }
// check and free the content buffer // check and free the content buffer
if (test->c_buffer != NULL) { if (test->c_buffer != NULL) {
xdb_free(test->c_buffer); xdb_close_content(test->c_buffer);
test->c_buffer = NULL; test->c_buffer = NULL;
} }
} }
......
...@@ -37,10 +37,9 @@ void test_check_ip() { ...@@ -37,10 +37,9 @@ void test_check_ip() {
} }
void test_load_header() { void test_load_header() {
xdb_header_t header; xdb_header_t *header = xdb_load_header_from_file("../../data/ip2region.xdb");
int err = xdb_load_header_from_file("../../data/ip2region.xdb", &header); if (header == NULL) {
if (err != 0) { printf("failed to load header");
printf("failed to load header with errcode=%d\n", err);
} else { } else {
printf("header loaded: {\n" printf("header loaded: {\n"
" version: %d, \n" " version: %d, \n"
...@@ -48,33 +47,36 @@ void test_load_header() { ...@@ -48,33 +47,36 @@ void test_load_header() {
" created_at: %u, \n" " created_at: %u, \n"
" start_index_ptr: %d, \n" " start_index_ptr: %d, \n"
" end_index_ptr: %d\n" " end_index_ptr: %d\n"
" length: %d\n"
"}\n", "}\n",
header.version, header.index_policy, header.created_at, header->version, header->index_policy, header->created_at,
header.start_index_ptr, header.end_index_ptr header->start_index_ptr, header->end_index_ptr, header->length
); );
} }
xdb_close_header(header);
} }
void test_load_vector_index() { void test_load_vector_index() {
char *ptr = xdb_load_vector_index_from_file("../../data/ip2region.xdb"); xdb_vector_index_t *v_index = xdb_load_vector_index_from_file("../../data/ip2region.xdb");
if (ptr == NULL) { if (v_index == NULL) {
printf("failed to load vector index from file\n"); printf("failed to load vector index from file\n");
} else { } else {
printf("vector index loaded from file\n"); printf("vector index loaded from file, length=%d\n", v_index->length);
} }
xdb_free(ptr); xdb_close_vector_index(v_index);
} }
void test_load_content() { void test_load_content() {
char *ptr = xdb_load_content_from_file("../../data/ip2region.xdb"); xdb_content_t *content = xdb_load_content_from_file("../../data/ip2region.xdb");
if (ptr == NULL) { if (content == NULL) {
printf("failed to load content from file\n"); printf("failed to load content from file\n");
} else { } else {
printf("content loaded from file\n"); printf("content loaded from file, length=%d\n", content->length);
} }
xdb_free(ptr); xdb_close_content(content);
} }
// valgrind --tool=memcheck --leak-check=full ./a.out // valgrind --tool=memcheck --leak-check=full ./a.out
......
...@@ -12,13 +12,13 @@ ...@@ -12,13 +12,13 @@
// internal function prototype define // internal function prototype define
XDB_PRIVATE(int) read(xdb_searcher_t *, long offset, char *, size_t length); XDB_PRIVATE(int) read(xdb_searcher_t *, long offset, char *, size_t length);
XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const char *vIndex, const char *cBuff) { XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index, const xdb_content_t *c_buffer) {
memset(xdb, 0x00, sizeof(xdb_searcher_t)); memset(xdb, 0x00, sizeof(xdb_searcher_t));
// check the content buffer first // check the content buffer first
if (cBuff != NULL) { if (c_buffer != NULL) {
xdb->vector_index = NULL; xdb->v_index = NULL;
xdb->content_buff = cBuff; xdb->content = c_buffer;
return 0; return 0;
} }
...@@ -29,7 +29,7 @@ XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const ch ...@@ -29,7 +29,7 @@ XDB_PRIVATE(int) xdb_new_base(xdb_searcher_t *xdb, const char *db_path, const ch
} }
xdb->handle = handle; xdb->handle = handle;
xdb->vector_index = vIndex; xdb->v_index = v_index;
return 0; return 0;
} }
...@@ -39,11 +39,11 @@ XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *xdb, const char *db_path) ...@@ -39,11 +39,11 @@ XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *xdb, const char *db_path)
return xdb_new_base(xdb, db_path, NULL, NULL); return xdb_new_base(xdb, db_path, NULL, NULL);
} }
XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *xdb, const char *db_path, const char *vIndex) { XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *xdb, const char *db_path, const xdb_vector_index_t *v_index) {
return xdb_new_base(xdb, db_path, vIndex, NULL); return xdb_new_base(xdb, db_path, v_index, NULL);
} }
XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *xdb, const char *c_buffer) { XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *xdb, const xdb_content_t *c_buffer) {
return xdb_new_base(xdb, NULL, NULL, c_buffer); return xdb_new_base(xdb, NULL, NULL, c_buffer);
} }
...@@ -78,12 +78,12 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu ...@@ -78,12 +78,12 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu
il0 = ((int) (ip >> 24)) & 0xFF; il0 = ((int) (ip >> 24)) & 0xFF;
il1 = ((int) (ip >> 16)) & 0xFF; il1 = ((int) (ip >> 16)) & 0xFF;
idx = il0 * xdb_vector_index_cols * xdb_vector_index_size + il1 * xdb_vector_index_size; idx = il0 * xdb_vector_index_cols * xdb_vector_index_size + il1 * xdb_vector_index_size;
if (xdb->vector_index != NULL) { if (xdb->v_index != NULL) {
s_ptr = xdb_get_uint(xdb->vector_index, idx); s_ptr = xdb_get_uint(xdb->v_index->buffer, idx);
e_ptr = xdb_get_uint(xdb->vector_index, idx + 4); e_ptr = xdb_get_uint(xdb->v_index->buffer, idx + 4);
} else if (xdb->content_buff != NULL) { } else if (xdb->content != NULL) {
s_ptr = xdb_get_uint(xdb->content_buff, xdb_header_info_length + idx); s_ptr = xdb_get_uint(xdb->content->buffer, xdb_header_info_length + idx);
e_ptr = xdb_get_uint(xdb->content_buff, xdb_header_info_length + idx + 4); e_ptr = xdb_get_uint(xdb->content->buffer, xdb_header_info_length + idx + 4);
} else { } else {
err = read(xdb, xdb_header_info_length + idx, vector_buffer, sizeof(vector_buffer)); err = read(xdb, xdb_header_info_length + idx, vector_buffer, sizeof(vector_buffer));
if (err != 0) { if (err != 0) {
...@@ -147,8 +147,8 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu ...@@ -147,8 +147,8 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *xdb, unsigned int ip, char *region_bu
XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t length) { XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t length) {
// check the xdb content cache first // check the xdb content cache first
if (xdb->content_buff != NULL) { if (xdb->content != NULL) {
memcpy(buffer, xdb->content_buff + offset, length); memcpy(buffer, xdb->content->buffer + offset, length);
return 0; return 0;
} }
...@@ -172,39 +172,58 @@ XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *xdb) { ...@@ -172,39 +172,58 @@ XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *xdb) {
// --- buffer load util functions // --- buffer load util functions
XDB_PUBLIC(int) xdb_load_header(FILE *handle, xdb_header_t *header) { XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *handle) {
char buffer[256]; xdb_header_t *header;
unsigned int size = xdb_header_info_length;
// entry alloc
header = (xdb_header_t *) xdb_malloc(sizeof(xdb_header_t));
if (header == NULL) {
return NULL;
}
if (fseek(handle, 0, SEEK_SET) == -1) { if (fseek(handle, 0, SEEK_SET) == -1) {
return 1; xdb_free(header);
return NULL;
} }
if (fread(buffer, 1, 256, handle) != 256) { if (fread(header->buffer, 1,size, handle) != size) {
return 2; xdb_free(header);
return NULL;
} }
// fill the fields // fill the fields
header->version = (unsigned short) xdb_get_ushort(buffer, 0); header->length = size;
header->index_policy = (unsigned short) xdb_get_ushort(buffer, 2); header->version = (unsigned short) xdb_get_ushort(header->buffer, 0);
header->created_at = xdb_get_uint(buffer, 4); header->index_policy = (unsigned short) xdb_get_ushort(header->buffer, 2);
header->start_index_ptr = xdb_get_uint(buffer, 8); header->created_at = xdb_get_uint(header->buffer, 4);
header->end_index_ptr = xdb_get_uint(buffer,12); header->start_index_ptr = xdb_get_uint(header->buffer, 8);
header->end_index_ptr = xdb_get_uint(header->buffer,12);
return 0;
return header;
} }
XDB_PUBLIC(int) xdb_load_header_from_file(const char *db_path, xdb_header_t *header) { XDB_PUBLIC(xdb_header_t *) xdb_load_header_from_file(const char *db_path) {
FILE *handle = fopen(db_path, "r"); FILE *handle = fopen(db_path, "r");
if (handle == NULL) { if (handle == NULL) {
return 10; return NULL;
} }
return xdb_load_header(handle, header); return xdb_load_header(handle);
}
XDB_PUBLIC(void) xdb_close_header(xdb_header_t *header) {
if (header->length > 0) {
header->length = 0;
xdb_free(header);
}
} }
XDB_PUBLIC(char *) xdb_load_vector_index(FILE *handle) { // --- vector index
char *ptr = NULL;
int size = xdb_vector_index_length; XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index(FILE *handle) {
xdb_vector_index_t *v_index;
unsigned int size = xdb_vector_index_length;
// seek to the vector index offset // seek to the vector index offset
if (fseek(handle, xdb_header_info_length, SEEK_SET) == -1) { if (fseek(handle, xdb_header_info_length, SEEK_SET) == -1) {
...@@ -212,20 +231,21 @@ XDB_PUBLIC(char *) xdb_load_vector_index(FILE *handle) { ...@@ -212,20 +231,21 @@ XDB_PUBLIC(char *) xdb_load_vector_index(FILE *handle) {
} }
// do the buffer read // do the buffer read
ptr = (char *) xdb_malloc(size); v_index = (xdb_vector_index_t *) xdb_malloc(sizeof(xdb_vector_index_t));
if (ptr == NULL) { if (v_index == NULL) {
return NULL; return NULL;
} }
if (fread(ptr, 1, size, handle) != size) { v_index->length = size;
xdb_free(ptr); if (fread(v_index->buffer, 1, size, handle) != size) {
xdb_free(v_index);
return NULL; return NULL;
} }
return ptr; return v_index;
} }
XDB_PUBLIC(char *) xdb_load_vector_index_from_file(const char *db_path) { XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index_from_file(const char *db_path) {
FILE *handle = fopen(db_path, "r"); FILE *handle = fopen(db_path, "r");
if (handle == NULL) { if (handle == NULL) {
return NULL; return NULL;
...@@ -234,36 +254,54 @@ XDB_PUBLIC(char *) xdb_load_vector_index_from_file(const char *db_path) { ...@@ -234,36 +254,54 @@ XDB_PUBLIC(char *) xdb_load_vector_index_from_file(const char *db_path) {
return xdb_load_vector_index(handle); return xdb_load_vector_index(handle);
} }
XDB_PUBLIC(char *) xdb_load_content(FILE *handle) { XDB_PUBLIC(void) xdb_close_vector_index(xdb_vector_index_t *v_index) {
long filesize; if (v_index->length > 0) {
char *ptr = NULL; v_index->length = 0;
xdb_free(v_index);
}
}
// --- content buffer
XDB_PUBLIC(xdb_content_t *) xdb_load_content(FILE *handle) {
unsigned int size;
xdb_content_t *content;
char *ptr;
// determine the file size // determine the file size
if (fseek(handle, 0, SEEK_END) == -1) { if (fseek(handle, 0, SEEK_END) == -1) {
return NULL; return NULL;
} }
filesize = ftell(handle); size = (unsigned int) ftell(handle);
if (fseek(handle, 0, SEEK_SET) == -1) { if (fseek(handle, 0, SEEK_SET) == -1) {
return NULL; return NULL;
} }
// do the file read // do the file read
ptr = (char *) xdb_malloc(filesize); content = (xdb_content_t *) xdb_malloc(sizeof(xdb_content_t));
if (ptr == NULL) { if (content == NULL) {
return NULL;
}
// do the buffer alloc
content->buffer = (char *) xdb_malloc(size);
if (content->buffer == NULL) {
xdb_free(content);
return NULL; return NULL;
} }
// read the content into the buffer // read the content into the buffer
if (fread(ptr, 1, filesize, handle) != filesize) { content->length = size;
if (fread(content->buffer, 1, size, handle) != size) {
xdb_free(ptr); xdb_free(ptr);
return NULL; return NULL;
} }
return ptr; return content;
} }
XDB_PUBLIC(char *) xdb_load_content_from_file(const char *db_path) { XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *db_path) {
FILE *handle = fopen(db_path, "r"); FILE *handle = fopen(db_path, "r");
if (handle == NULL) { if (handle == NULL) {
return NULL; return NULL;
...@@ -272,6 +310,15 @@ XDB_PUBLIC(char *) xdb_load_content_from_file(const char *db_path) { ...@@ -272,6 +310,15 @@ XDB_PUBLIC(char *) xdb_load_content_from_file(const char *db_path) {
return xdb_load_content(handle); return xdb_load_content(handle);
} }
XDB_PUBLIC(void) xdb_close_content(xdb_content_t *content) {
if (content->length > 0) {
content->length = 0;
xdb_free(content->buffer);
content->buffer = NULL;
xdb_free(content);
}
}
// --- End // --- End
// get unsigned long (4bytes) from a specified buffer start from the specified offset // get unsigned long (4bytes) from a specified buffer start from the specified offset
......
...@@ -38,6 +38,59 @@ ...@@ -38,6 +38,59 @@
#define xdb_vector_index_length 524288 #define xdb_vector_index_length 524288
// --- buffer load util functions
// use the following buffer struct to wrap the binary buffer data
// since the buffer data could not be operated with the string API.
struct xdb_header {
unsigned short version;
unsigned short index_policy;
unsigned int created_at;
unsigned int start_index_ptr;
unsigned int end_index_ptr;
// the original buffer
unsigned int length;
char buffer[xdb_header_info_length];
};
typedef struct xdb_header xdb_header_t;
XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *);
XDB_PUBLIC(xdb_header_t *) xdb_load_header_from_file(const char *);
XDB_PUBLIC(void) xdb_close_header(xdb_header_t *);
// --- vector index buffer
struct xdb_vector_index {
unsigned int length;
char buffer[xdb_vector_index_length];
};
typedef struct xdb_vector_index xdb_vector_index_t;
XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index(FILE *);
XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index_from_file(const char *);
XDB_PUBLIC(void) xdb_close_vector_index(xdb_vector_index_t *);
// --- content buffer
struct xdb_content {
unsigned int length;
char *buffer;
};
typedef struct xdb_content xdb_content_t;
XDB_PUBLIC(xdb_content_t *) xdb_load_content(FILE *);
XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *);
XDB_PUBLIC(void) xdb_close_content(xdb_content_t *);
// --- End buffer load
// xdb searcher structure // xdb searcher structure
struct xdb_searcher_entry { struct xdb_searcher_entry {
FILE *handle; FILE *handle;
...@@ -49,20 +102,20 @@ struct xdb_searcher_entry { ...@@ -49,20 +102,20 @@ struct xdb_searcher_entry {
// vector index buffer cache. // vector index buffer cache.
// preload the vector index will reduce the number of IO operations // preload the vector index will reduce the number of IO operations
// thus speedup the search process. // thus speedup the search process.
const char *vector_index; const xdb_vector_index_t *v_index;
// content buffer. // content buffer.
// cache the whole xdb content. // cache the whole xdb content.
const char *content_buff; const xdb_content_t *content;
}; };
typedef struct xdb_searcher_entry xdb_searcher_t; typedef struct xdb_searcher_entry xdb_searcher_t;
// xdb searcher new api define // xdb searcher new api define
XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *, const char *); XDB_PUBLIC(int) xdb_new_with_file_only(xdb_searcher_t *, const char *);
XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *, const char *, const char *); XDB_PUBLIC(int) xdb_new_with_vector_index(xdb_searcher_t *, const char *, const xdb_vector_index_t *);
XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *, const char *); XDB_PUBLIC(int) xdb_new_with_buffer(xdb_searcher_t *, const xdb_content_t *);
XDB_PUBLIC(void) xdb_close(xdb_searcher_t *); XDB_PUBLIC(void) xdb_close(xdb_searcher_t *);
...@@ -74,32 +127,6 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *, unsigned int, char *, size_t); ...@@ -74,32 +127,6 @@ XDB_PUBLIC(int) xdb_search(xdb_searcher_t *, unsigned int, char *, size_t);
XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *); XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *);
// --- buffer load util functions
struct xdb_header {
unsigned short version;
unsigned short index_policy;
unsigned int created_at;
unsigned int start_index_ptr;
unsigned int end_index_ptr;
};
typedef struct xdb_header xdb_header_t;
XDB_PUBLIC(int) xdb_load_header(FILE *, xdb_header_t *);
XDB_PUBLIC(int) xdb_load_header_from_file(const char *, xdb_header_t *);
XDB_PUBLIC(char *) xdb_load_vector_index(FILE *);
XDB_PUBLIC(char *) xdb_load_vector_index_from_file(const char *);
XDB_PUBLIC(char *) xdb_load_content(FILE *);
XDB_PUBLIC(char *) xdb_load_content_from_file(const char *);
// --- End buffer load
// get unsigned long (4bytes) from a specified buffer start from the specified offset with little-endian // 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); XDB_PUBLIC(unsigned int) xdb_get_uint(const char *, int);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册