add #ip2region_memory_search interface for memory search
This commit is contained in:
parent
dbf94ef586
commit
861b8b4622
|
|
@ -35,12 +35,15 @@ IP2R_API uint_t ip2region_create(ip2region_t ip2rObj, char *dbFile)
|
||||||
if ( ip2rObj->dbHandler == NULL ) {
|
if ( ip2rObj->dbHandler == NULL ) {
|
||||||
IP2R_FREE(ip2rObj->HeaderSip);
|
IP2R_FREE(ip2rObj->HeaderSip);
|
||||||
IP2R_FREE(ip2rObj->HeaderPtr);
|
IP2R_FREE(ip2rObj->HeaderPtr);
|
||||||
|
//fprintf(stderr, "Fail to open the db file %s\n", ip2rObj>dbFile);
|
||||||
|
//exit(-1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip2rObj->firstIndexPtr = 0;
|
ip2rObj->firstIndexPtr = 0;
|
||||||
ip2rObj->lastIndexPtr = 0;
|
ip2rObj->lastIndexPtr = 0;
|
||||||
ip2rObj->totalBlocks = 0;
|
ip2rObj->totalBlocks = 0;
|
||||||
|
ip2rObj->dbBinStr = NULL;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -63,9 +66,94 @@ IP2R_API uint_t ip2region_destroy(ip2region_t ip2rObj)
|
||||||
ip2rObj->dbHandler = NULL;
|
ip2rObj->dbHandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//free the db binary string
|
||||||
|
if ( ip2rObj->dbBinStr != NULL ) {
|
||||||
|
IP2R_FREE(ip2rObj->dbBinStr);
|
||||||
|
ip2rObj->dbBinStr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the region associated with the specified ip address with the memory binary search algorithm
|
||||||
|
*
|
||||||
|
* @param ip2rObj
|
||||||
|
* @param ip
|
||||||
|
* @param datablock
|
||||||
|
*/
|
||||||
|
IP2R_API uint_t ip2region_memory_search(ip2region_t ip2rObj, uint_t ip, datablock_t datablock)
|
||||||
|
{
|
||||||
|
int l, h, m, p;
|
||||||
|
uint_t sip, eip, dptr;
|
||||||
|
int dataLen, dataptr;
|
||||||
|
long filesize;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
if ( ip2rObj->dbBinStr == NULL ) {
|
||||||
|
//get the size of the file
|
||||||
|
fseek(ip2rObj->dbHandler, 0, SEEK_END);
|
||||||
|
filesize = ftell(ip2rObj->dbHandler);
|
||||||
|
fseek(ip2rObj->dbHandler, 0, SEEK_SET);
|
||||||
|
|
||||||
|
//alloc the buffer size
|
||||||
|
ip2rObj->dbBinStr = IP2R_MALLOC(filesize);
|
||||||
|
if ( ip2rObj->dbBinStr == NULL ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//now read the whole file
|
||||||
|
if ( fread(ip2rObj->dbBinStr, filesize, 1, ip2rObj->dbHandler) != 1 ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = ip2rObj->dbBinStr;
|
||||||
|
ip2rObj->firstIndexPtr = getUnsignedInt(buffer, 0);
|
||||||
|
ip2rObj->lastIndexPtr = getUnsignedInt(buffer, 4);
|
||||||
|
ip2rObj->totalBlocks = (ip2rObj->lastIndexPtr-ip2rObj->firstIndexPtr)/INDEX_BLOCK_LENGTH + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = 0; h = ip2rObj->totalBlocks; dptr = 0;
|
||||||
|
while ( l <= h ) {
|
||||||
|
m = (l + h) >> 1;
|
||||||
|
p = ip2rObj->firstIndexPtr + m * INDEX_BLOCK_LENGTH;
|
||||||
|
|
||||||
|
buffer = ip2rObj->dbBinStr + p;
|
||||||
|
sip = getUnsignedInt(buffer, 0);
|
||||||
|
if ( ip < sip ) {
|
||||||
|
h = m - 1;
|
||||||
|
} else {
|
||||||
|
eip = getUnsignedInt(buffer, 4);
|
||||||
|
if ( ip > eip ) {
|
||||||
|
l = m + 1;
|
||||||
|
} else {
|
||||||
|
dptr = getUnsignedInt(buffer, 8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dptr == 0 ) return 0;
|
||||||
|
|
||||||
|
//get the data
|
||||||
|
dataLen = ((dptr >> 24) & 0xFF);
|
||||||
|
dataptr = (dptr & 0x00FFFFFF);
|
||||||
|
buffer = ip2rObj->dbBinStr + dataptr;
|
||||||
|
|
||||||
|
//fill the data to the datablock
|
||||||
|
datablock->city_id = getUnsignedInt(buffer, 0);
|
||||||
|
dataLen -= 4; //reduce the length of the city_id
|
||||||
|
memcpy(datablock->region, buffer + 4, dataLen);
|
||||||
|
datablock->region[dataLen] = '\0';
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
IP2R_API uint_t ip2region_memory_search_string(ip2region_t ip2rObj, char *ip, datablock_t datablock)
|
||||||
|
{
|
||||||
|
return ip2region_memory_search(ip2rObj, ip2long(ip), datablock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the region associated with the specifield ip address with binary search algorithm
|
* get the region associated with the specifield ip address with binary search algorithm
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ typedef struct {
|
||||||
uint_t *HeaderSip; //header start ip blocks
|
uint_t *HeaderSip; //header start ip blocks
|
||||||
uint_t *HeaderPtr; //header ptr blocks
|
uint_t *HeaderPtr; //header ptr blocks
|
||||||
uint_t headerLen; //header block number
|
uint_t headerLen; //header block number
|
||||||
|
char *dbFile; //path of db file
|
||||||
FILE *dbHandler; //file handler
|
FILE *dbHandler; //file handler
|
||||||
|
char *dbBinStr; //db binary string for memory search mode
|
||||||
|
|
||||||
uint_t firstIndexPtr; //first index ptr
|
uint_t firstIndexPtr; //first index ptr
|
||||||
uint_t lastIndexPtr; //last index ptr
|
uint_t lastIndexPtr; //last index ptr
|
||||||
|
|
@ -79,14 +81,26 @@ typedef datablock_entry * datablock_t;
|
||||||
IP2R_API uint_t ip2region_create(ip2region_t, char *);
|
IP2R_API uint_t ip2region_create(ip2region_t, char *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* destroy the specifield ip2region object
|
* destroy the specified ip2region object
|
||||||
*
|
*
|
||||||
* @param ip2region_t
|
* @param ip2region_t
|
||||||
*/
|
*/
|
||||||
IP2R_API uint_t ip2region_destroy(ip2region_t);
|
IP2R_API uint_t ip2region_destroy(ip2region_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the region associated with the specifield ip address with binary search algorithm
|
* get the region associated with the specified ip address with the memory binary search algorithm
|
||||||
|
*
|
||||||
|
* @param ip2region_t
|
||||||
|
* @param uint_t
|
||||||
|
* @param datablock_t
|
||||||
|
* @date 2016/06/30
|
||||||
|
*/
|
||||||
|
IP2R_API uint_t ip2region_memory_search(ip2region_t, uint_t, datablock_t);
|
||||||
|
IP2R_API uint_t ip2region_memory_search_string(ip2region_t, char *, datablock_t);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the region associated with the specified ip address with binary search algorithm
|
||||||
*
|
*
|
||||||
* @param ip2rObj
|
* @param ip2rObj
|
||||||
* @param ip
|
* @param ip
|
||||||
|
|
@ -97,7 +111,7 @@ IP2R_API uint_t ip2region_binary_search(ip2region_t, uint_t, datablock_t);
|
||||||
IP2R_API uint_t ip2region_binary_search_string(ip2region_t, char *, datablock_t);
|
IP2R_API uint_t ip2region_binary_search_string(ip2region_t, char *, datablock_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the region associated with the specifield ip address with b-tree algorithm
|
* get the region associated with the specified ip address with b-tree algorithm
|
||||||
*
|
*
|
||||||
* @param ip2rObj
|
* @param ip2rObj
|
||||||
* @param ip
|
* @param ip
|
||||||
|
|
@ -108,7 +122,7 @@ IP2R_API uint_t ip2region_btree_search(ip2region_t, uint_t, datablock_t);
|
||||||
IP2R_API uint_t ip2region_btree_search_string(ip2region_t, char *, datablock_t);
|
IP2R_API uint_t ip2region_btree_search_string(ip2region_t, char *, datablock_t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get a unsinged long(4bytes) from a specifield buffer start from the specifield offset
|
* get a unsinged long(4bytes) from a specified buffer start from the specified offset
|
||||||
*
|
*
|
||||||
* @param buffer
|
* @param buffer
|
||||||
* @param offset
|
* @param offset
|
||||||
|
|
|
||||||
|
|
@ -54,22 +54,27 @@ int main( int argc, char **argv )
|
||||||
memset(&datablock, 0x00, sizeof(datablock_entry));
|
memset(&datablock, 0x00, sizeof(datablock_entry));
|
||||||
|
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
printf("Usage: a.out [ip2region db file path] [algorithm]");
|
printf("Usage: a.out [ip2region db file path] [algorithm]\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbFile = argv[1];
|
dbFile = argv[1];
|
||||||
algorithm = "B-tree";
|
algorithm = "B-tree";
|
||||||
func_ptr = ip2region_btree_search_string;
|
func_ptr = ip2region_btree_search_string;
|
||||||
if ( argc >= 3 && strcmp(argv[2], "binary") == 0 ) {
|
if ( argc >= 3 ) {
|
||||||
algorithm = "Binary";
|
if ( strcmp(argv[2], "binary") == 0 ) {
|
||||||
func_ptr = ip2region_binary_search_string;
|
algorithm = "Binary";
|
||||||
|
func_ptr = ip2region_binary_search_string;
|
||||||
|
} else if ( strcmp(argv[2], "memory") == 0 ) {
|
||||||
|
algorithm = "Memory";
|
||||||
|
func_ptr = ip2region_memory_search_string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a new ip2rObj
|
//create a new ip2rObj
|
||||||
printf("+--initializing %s ... \n", algorithm);
|
printf("+--initializing %s ... \n", algorithm);
|
||||||
if ( ip2region_create(&ip2rEntry, dbFile) == 0 ) {
|
if ( ip2region_create(&ip2rEntry, dbFile) == 0 ) {
|
||||||
println("Error: Fail to create the ip2region object");
|
println("Error: Fail to create the ip2region object\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue