add DbSearcher#memorySearch interface
This commit is contained in:
parent
861b8b4622
commit
a5df8ff87c
|
|
@ -12,7 +12,8 @@ import java.io.RandomAccessFile;
|
|||
public class DbSearcher
|
||||
{
|
||||
public static final int BTREE_ALGORITHM = 1;
|
||||
public static final int BIN_ALGORITHM = 2;
|
||||
public static final int BINARY_ALGORITHM = 2;
|
||||
public static final int MEMORY_ALGORITYM = 3;
|
||||
|
||||
/**
|
||||
* db config
|
||||
|
|
@ -38,6 +39,12 @@ public class DbSearcher
|
|||
private long lastIndexPtr = 0;
|
||||
private int totalIndexBlocks = 0;
|
||||
|
||||
/**
|
||||
* for memory mode
|
||||
* the original db binary string
|
||||
*/
|
||||
private byte[] dbBinStr = null;
|
||||
|
||||
/**
|
||||
* construct class
|
||||
*
|
||||
|
|
@ -51,6 +58,72 @@ public class DbSearcher
|
|||
raf = new RandomAccessFile(dbFile, "r");
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region with a int ip address with memory binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock memorySearch(long ip) throws IOException
|
||||
{
|
||||
int blen = IndexBlock.getIndexBlockLength();
|
||||
if ( dbBinStr == null ) {
|
||||
dbBinStr = new byte[(int)raf.length()];
|
||||
raf.seek(0L);
|
||||
raf.readFully(dbBinStr, 0, dbBinStr.length);
|
||||
|
||||
//initialize the global vars
|
||||
firstIndexPtr = Util.getIntLong(dbBinStr, 0);
|
||||
lastIndexPtr = Util.getIntLong(dbBinStr, 4);
|
||||
totalIndexBlocks = (int)((lastIndexPtr - firstIndexPtr)/blen) + 1;
|
||||
}
|
||||
|
||||
//search the index blocks to define the data
|
||||
int l = 0, h = totalIndexBlocks;
|
||||
long sip, eip, dataptr = 0;
|
||||
while ( l <= h ) {
|
||||
int m = (l + h) >> 1;
|
||||
int p = (int)(firstIndexPtr + m * blen);
|
||||
|
||||
sip = Util.getIntLong(dbBinStr, p);
|
||||
if ( ip < sip ) {
|
||||
h = m - 1;
|
||||
} else {
|
||||
eip = Util.getIntLong(dbBinStr, p + 4);
|
||||
if ( ip > eip ) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
dataptr = Util.getIntLong(dbBinStr, p + 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//not matched
|
||||
if ( dataptr == 0 ) return null;
|
||||
|
||||
//get the data
|
||||
int dataLen = (int)((dataptr >> 24) & 0xFF);
|
||||
int dataPtr = (int)((dataptr & 0x00FFFFFF));
|
||||
int city_id = (int)Util.getIntLong(dbBinStr, dataPtr);
|
||||
String region = new String(dbBinStr, dataPtr + 4, dataLen - 4, "UTF-8");
|
||||
|
||||
return new DataBlock(city_id, region, dataPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region throught the ip address with memory binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @return DataBlock
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock memorySearch( String ip ) throws IOException
|
||||
{
|
||||
return memorySearch(Util.ip2long(ip));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get by index ptr
|
||||
*
|
||||
|
|
@ -308,6 +381,8 @@ public class DbSearcher
|
|||
{
|
||||
HeaderSip = null; //let gc do its work
|
||||
HeaderPtr = null;
|
||||
dbBinStr = null;
|
||||
raf.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import java.io.BufferedReader;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.lionsoul.ip2region.DataBlock;
|
||||
import org.lionsoul.ip2region.DbConfig;
|
||||
|
|
@ -25,23 +27,45 @@ public class TestSearcher
|
|||
return;
|
||||
}
|
||||
|
||||
int algorithm = DbSearcher.BTREE_ALGORITHM;
|
||||
File file = new File(argv[0]);
|
||||
if ( file.exists() == false ) {
|
||||
System.out.println("Error: Invalid ip2region.db file");
|
||||
return;
|
||||
}
|
||||
|
||||
int algorithm = DbSearcher.BTREE_ALGORITHM;
|
||||
String algoName = "B-tree";
|
||||
if ( argv.length > 1 ) {
|
||||
if ( argv[1].equalsIgnoreCase("binary")) algorithm = DbSearcher.BIN_ALGORITHM;
|
||||
if ( argv[1].equalsIgnoreCase("binary")) {
|
||||
algoName = "Binary";
|
||||
algorithm = DbSearcher.BINARY_ALGORITHM;
|
||||
} else if ( argv[1].equalsIgnoreCase("memory") ) {
|
||||
algoName = "Memory";
|
||||
algorithm = DbSearcher.MEMORY_ALGORITYM;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
System.out.println("initializing "+((algorithm==2)?"Binary":"B-tree")+" ... ");
|
||||
System.out.println("initializing "+algoName+" ... ");
|
||||
DbConfig config = new DbConfig();
|
||||
DbSearcher seacher = new DbSearcher(config, argv[0]);
|
||||
DbSearcher searcher = new DbSearcher(config, argv[0]);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
|
||||
//define the method
|
||||
Method method = null;
|
||||
switch ( algorithm )
|
||||
{
|
||||
case DbSearcher.BTREE_ALGORITHM:
|
||||
method = searcher.getClass().getMethod("btreeSearch", String.class);
|
||||
break;
|
||||
case DbSearcher.BINARY_ALGORITHM:
|
||||
method = searcher.getClass().getMethod("binarySearch", String.class);
|
||||
break;
|
||||
case DbSearcher.MEMORY_ALGORITYM:
|
||||
method = searcher.getClass().getMethod("memorySearch", String.class);
|
||||
break;
|
||||
}
|
||||
|
||||
System.out.println("+----------------------------------+");
|
||||
System.out.println("| ip2region test shell |");
|
||||
System.out.println("| Author: chenxin619315@gmail.com |");
|
||||
|
|
@ -62,13 +86,13 @@ public class TestSearcher
|
|||
}
|
||||
|
||||
sTime = System.nanoTime();
|
||||
dataBlock = algorithm==2 ? seacher.binarySearch(line) : seacher.btreeSearch(line);
|
||||
dataBlock = (DataBlock) method.invoke(searcher, line);
|
||||
cTime = (System.nanoTime() - sTime) / 1000000;
|
||||
System.out.printf("%s in %.5f millseconds\n", dataBlock, cTime);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
seacher.close();
|
||||
searcher.close();
|
||||
System.out.println("+--Bye");
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
|
|
@ -76,6 +100,21 @@ public class TestSearcher
|
|||
} catch (DbMakerConfigException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue