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 class DbSearcher
|
||||||
{
|
{
|
||||||
public static final int BTREE_ALGORITHM = 1;
|
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
|
* db config
|
||||||
|
|
@ -38,6 +39,12 @@ public class DbSearcher
|
||||||
private long lastIndexPtr = 0;
|
private long lastIndexPtr = 0;
|
||||||
private int totalIndexBlocks = 0;
|
private int totalIndexBlocks = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for memory mode
|
||||||
|
* the original db binary string
|
||||||
|
*/
|
||||||
|
private byte[] dbBinStr = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* construct class
|
* construct class
|
||||||
*
|
*
|
||||||
|
|
@ -51,6 +58,72 @@ public class DbSearcher
|
||||||
raf = new RandomAccessFile(dbFile, "r");
|
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
|
* get by index ptr
|
||||||
*
|
*
|
||||||
|
|
@ -308,6 +381,8 @@ public class DbSearcher
|
||||||
{
|
{
|
||||||
HeaderSip = null; //let gc do its work
|
HeaderSip = null; //let gc do its work
|
||||||
HeaderPtr = null;
|
HeaderPtr = null;
|
||||||
|
dbBinStr = null;
|
||||||
raf.close();
|
raf.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.lionsoul.ip2region.DataBlock;
|
import org.lionsoul.ip2region.DataBlock;
|
||||||
import org.lionsoul.ip2region.DbConfig;
|
import org.lionsoul.ip2region.DbConfig;
|
||||||
|
|
@ -25,23 +27,45 @@ public class TestSearcher
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int algorithm = DbSearcher.BTREE_ALGORITHM;
|
|
||||||
File file = new File(argv[0]);
|
File file = new File(argv[0]);
|
||||||
if ( file.exists() == false ) {
|
if ( file.exists() == false ) {
|
||||||
System.out.println("Error: Invalid ip2region.db file");
|
System.out.println("Error: Invalid ip2region.db file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int algorithm = DbSearcher.BTREE_ALGORITHM;
|
||||||
|
String algoName = "B-tree";
|
||||||
if ( argv.length > 1 ) {
|
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 {
|
try {
|
||||||
System.out.println("initializing "+((algorithm==2)?"Binary":"B-tree")+" ... ");
|
System.out.println("initializing "+algoName+" ... ");
|
||||||
DbConfig config = new DbConfig();
|
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));
|
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("+----------------------------------+");
|
||||||
System.out.println("| ip2region test shell |");
|
System.out.println("| ip2region test shell |");
|
||||||
System.out.println("| Author: chenxin619315@gmail.com |");
|
System.out.println("| Author: chenxin619315@gmail.com |");
|
||||||
|
|
@ -62,13 +86,13 @@ public class TestSearcher
|
||||||
}
|
}
|
||||||
|
|
||||||
sTime = System.nanoTime();
|
sTime = System.nanoTime();
|
||||||
dataBlock = algorithm==2 ? seacher.binarySearch(line) : seacher.btreeSearch(line);
|
dataBlock = (DataBlock) method.invoke(searcher, line);
|
||||||
cTime = (System.nanoTime() - sTime) / 1000000;
|
cTime = (System.nanoTime() - sTime) / 1000000;
|
||||||
System.out.printf("%s in %.5f millseconds\n", dataBlock, cTime);
|
System.out.printf("%s in %.5f millseconds\n", dataBlock, cTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.close();
|
reader.close();
|
||||||
seacher.close();
|
searcher.close();
|
||||||
System.out.println("+--Bye");
|
System.out.println("+--Bye");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
|
|
@ -76,6 +100,21 @@ public class TestSearcher
|
||||||
} catch (DbMakerConfigException e) {
|
} catch (DbMakerConfigException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
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