clean code

This commit is contained in:
Killer 2020-06-10 18:13:42 +08:00
parent 1bb1f7cd50
commit 37c6349f10
2 changed files with 142 additions and 116 deletions

View File

@ -1,57 +1,54 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
namespace DbMaker namespace DbMaker
{ {
/// <summary> /// <summary>
/// ip db searcher class (Not thread safe) /// ip db searcher class (Not thread safe)
/// </summary> /// </summary>
public class DbSearcher public class DbSearcher : IDisposable
{ {
public const int BTREE_ALGORITHM = 1; public const int BTREE_ALGORITHM = 1;
public const int BINARY_ALGORITHM = 2; public const int BINARY_ALGORITHM = 2;
public const int MEMORY_ALGORITYM = 3; public const int MEMORY_ALGORITYM = 3;
/** /**
* db config * for memory mode
* the original db binary string
*/ */
private DbConfig dbConfig = null; private byte[] dbBinStr;
/**
* super blocks info
*/
private long firstIndexPtr;
private int headerLength;
private int[] HeaderPtr;
/**
* header blocks buffer
*/
private long[] HeaderSip;
private long lastIndexPtr;
/** /**
* db file access handler * db file access handler
*/ */
private Stream raf = null; private readonly Stream raf;
/** private int totalIndexBlocks;
* header blocks buffer
*/
private long[] HeaderSip = null;
private int[] HeaderPtr = null;
private int headerLength;
/**
* super blocks info
*/
private long firstIndexPtr = 0;
private long lastIndexPtr = 0;
private int totalIndexBlocks = 0;
/**
* for memory mode
* the original db binary string
*/
private byte[] dbBinStr = null;
/** /**
* construct class * construct class
* *
* @param bdConfig * @param bdConfig
* @param dbFile * @param dbFile
* @throws FileNotFoundException * @throws FileNotFoundException
*/ */
public DbSearcher(DbConfig dbConfig, String dbFile) public DbSearcher(DbConfig dbConfig, string dbFile)
{ {
this.dbConfig = dbConfig; this.dbConfig = dbConfig;
raf = File.OpenRead(dbFile); //new RandomAccessFile(dbFile, "r"); raf = File.OpenRead(dbFile); //new RandomAccessFile(dbFile, "r");
@ -71,7 +68,17 @@ namespace DbMaker
firstIndexPtr = Util.getIntLong(dbBinStr, 0); firstIndexPtr = Util.getIntLong(dbBinStr, 0);
lastIndexPtr = Util.getIntLong(dbBinStr, 4); lastIndexPtr = Util.getIntLong(dbBinStr, 4);
totalIndexBlocks = (int)((lastIndexPtr - firstIndexPtr) / IndexBlock.GetIndexBlockLength()) + 1; totalIndexBlocks = (int) ((lastIndexPtr - firstIndexPtr) / IndexBlock.GetIndexBlockLength()) + 1;
}
/**
* db config
*/
public DbConfig dbConfig { get; set; }
public void Dispose()
{
Close();
} }
/** /**
@ -80,19 +87,19 @@ namespace DbMaker
* @param ip * @param ip
* @throws IOException * @throws IOException
*/ */
public DataBlock memorySearch(long ip) public DataBlock MemorySearch(long ip)
{ {
int blen = IndexBlock.GetIndexBlockLength(); var blen = IndexBlock.GetIndexBlockLength();
if (dbBinStr == null) if (dbBinStr == null)
{ {
dbBinStr = new byte[(int)raf.Length]; dbBinStr = new byte[(int) raf.Length];
raf.Seek(0L, SeekOrigin.Begin); raf.Seek(0L, SeekOrigin.Begin);
//raf.readFully(dbBinStr, 0, dbBinStr.length); //raf.readFully(dbBinStr, 0, dbBinStr.length);
raf.Read(dbBinStr, 0, dbBinStr.Length); raf.Read(dbBinStr, 0, dbBinStr.Length);
//initialize the global vars //initialize the global vars
firstIndexPtr = Util.getIntLong(dbBinStr, 0); firstIndexPtr = Util.getIntLong(dbBinStr, 0);
lastIndexPtr = Util.getIntLong(dbBinStr, 4); lastIndexPtr = Util.getIntLong(dbBinStr, 4);
totalIndexBlocks = (int)((lastIndexPtr - firstIndexPtr) / blen) + 1; totalIndexBlocks = (int) ((lastIndexPtr - firstIndexPtr) / blen) + 1;
} }
//search the index blocks to define the data //search the index blocks to define the data
@ -100,8 +107,8 @@ namespace DbMaker
long sip, eip, dataptr = 0; long sip, eip, dataptr = 0;
while (l <= h) while (l <= h)
{ {
int m = (l + h) >> 1; var m = l + h >> 1;
int p = (int)(firstIndexPtr + m * blen); var p = (int) (firstIndexPtr + m * blen);
sip = Util.getIntLong(dbBinStr, p); sip = Util.getIntLong(dbBinStr, p);
if (ip < sip) if (ip < sip)
@ -124,12 +131,15 @@ namespace DbMaker
} }
//not matched //not matched
if (dataptr == 0) return null; if (dataptr == 0)
{
return null;
}
//get the data //get the data
int dataLen = (int)((dataptr >> 24) & 0xFF); var dataLen = (int) (dataptr >> 24 & 0xFF);
int dataPtr = (int)((dataptr & 0x00FFFFFF)); var dataPtr = (int) (dataptr & 0x00FFFFFF);
int city_id = (int)Util.getIntLong(dbBinStr, dataPtr); var city_id = (int) Util.getIntLong(dbBinStr, dataPtr);
//String region = new String(dbBinStr, dataPtr + 4, dataLen - 4, "UTF-8"); //String region = new String(dbBinStr, dataPtr + 4, dataLen - 4, "UTF-8");
var region = Encoding.UTF8.GetString(dbBinStr, dataPtr + 4, dataLen - 4); var region = Encoding.UTF8.GetString(dbBinStr, dataPtr + 4, dataLen - 4);
return new DataBlock(city_id, region, dataPtr); return new DataBlock(city_id, region, dataPtr);
@ -140,11 +150,11 @@ namespace DbMaker
* *
* @param ip * @param ip
* @return DataBlock * @return DataBlock
* @throws IOException * @throws IOException
*/ */
public DataBlock memorySearch(String ip) public DataBlock MemorySearch(string ip)
{ {
return memorySearch(Util.ip2long(ip)); return MemorySearch(Util.ip2long(ip));
} }
@ -152,29 +162,29 @@ namespace DbMaker
* get by index ptr * get by index ptr
* *
* @param indexPtr * @param indexPtr
* @throws IOException * @throws IOException
*/ */
public DataBlock getByIndexPtr(long ptr) public DataBlock GetByIndexPtr(long ptr)
{ {
raf.Seek(ptr, SeekOrigin.Begin); raf.Seek(ptr, SeekOrigin.Begin);
byte[] var
buffer = new byte[12]; buffer = new byte[12];
//raf.readFully(buffer, 0, buffer.length); //raf.readFully(buffer, 0, buffer.length);
raf.Read(buffer, 0, buffer.Length); raf.Read(buffer, 0, buffer.Length);
//long startIp = Util.getIntLong(buffer, 0); //long startIp = Util.getIntLong(buffer, 0);
//long endIp = Util.getIntLong(buffer, 4); //long endIp = Util.getIntLong(buffer, 4);
long extra = Util.getIntLong(buffer, 8); var extra = Util.getIntLong(buffer, 8);
int dataLen = (int)((extra >> 24) & 0xFF); var dataLen = (int) (extra >> 24 & 0xFF);
int dataPtr = (int)((extra & 0x00FFFFFF)); var dataPtr = (int) (extra & 0x00FFFFFF);
raf.Seek(dataPtr, SeekOrigin.Begin); raf.Seek(dataPtr, SeekOrigin.Begin);
byte[] data = new byte[dataLen]; var data = new byte[dataLen];
//raf.readFully(data, 0, data.length); //raf.readFully(data, 0, data.length);
raf.Read(data, 0, data.Length); raf.Read(data, 0, data.Length);
int city_id = (int)Util.getIntLong(data, 0); var city_id = (int) Util.getIntLong(data, 0);
//String region = new String(data, 4, data.length - 4, "UTF-8"); //String region = new String(data, 4, data.length - 4, "UTF-8");
String region = Encoding.UTF8.GetString(data, 4, data.Length - 4); var region = Encoding.UTF8.GetString(data, 4, data.Length - 4);
return new DataBlock(city_id, region, dataPtr); return new DataBlock(city_id, region, dataPtr);
} }
@ -182,34 +192,37 @@ namespace DbMaker
* get the region with a int ip address with b-tree algorithm * get the region with a int ip address with b-tree algorithm
* *
* @param ip * @param ip
* @throws IOException * @throws IOException
*/ */
public DataBlock btreeSearch(long ip) public DataBlock BTreeSearch(long ip)
{ {
//check and load the header //check and load the header
if (HeaderSip == null) if (HeaderSip == null)
{ {
//raf.seek(8L); //pass the super block //raf.seek(8L); //pass the super block
raf.Seek(8, SeekOrigin.Begin); raf.Seek(8, SeekOrigin.Begin);
byte[] b = new byte[dbConfig.TotalHeaderSize]; var b = new byte[dbConfig.TotalHeaderSize];
// byte[] b = new byte[4096]; // byte[] b = new byte[4096];
//raf.readFully(b, 0, b.length); //raf.readFully(b, 0, b.length);
raf.Read(b, 0, b.Length); raf.Read(b, 0, b.Length);
//fill the header //fill the header
int len = b.Length >> 3, idx = 0; //b.lenght / 8 int len = b.Length >> 3, idx = 0; //b.lenght / 8
HeaderSip = new long[len]; HeaderSip = new long[len];
HeaderPtr = new int[len]; HeaderPtr = new int[len];
long startIp; long startIp;
long xDataPtr = 0; long xDataPtr = 0;
for (int i = 0; i < b.Length; i += 8) for (var i = 0; i < b.Length; i += 8)
{ {
startIp = Util.getIntLong(b, i); startIp = Util.getIntLong(b, i);
xDataPtr = Util.getIntLong(b, i + 4); xDataPtr = Util.getIntLong(b, i + 4);
if (xDataPtr == 0) break; if (xDataPtr == 0)
{
break;
}
HeaderSip[idx] = startIp; HeaderSip[idx] = startIp;
HeaderPtr[idx] = (int)xDataPtr; HeaderPtr[idx] = (int) xDataPtr;
idx++; idx++;
} }
@ -219,17 +232,18 @@ namespace DbMaker
//1. define the index block with the binary search //1. define the index block with the binary search
if (ip == HeaderSip[0]) if (ip == HeaderSip[0])
{ {
return getByIndexPtr(HeaderPtr[0]); return GetByIndexPtr(HeaderPtr[0]);
} }
else if (ip == HeaderSip[headerLength - 1])
if (ip == HeaderSip[headerLength - 1])
{ {
return getByIndexPtr(HeaderPtr[headerLength - 1]); return GetByIndexPtr(HeaderPtr[headerLength - 1]);
} }
int l = 0, h = headerLength, sptr = 0, eptr = 0; int l = 0, h = headerLength, sptr = 0, eptr = 0;
while (l <= h) while (l <= h)
{ {
int m = (l + h) >> 1; var m = l + h >> 1;
//perfetc matched, just return it //perfetc matched, just return it
if (ip == HeaderSip[m]) if (ip == HeaderSip[m])
@ -257,12 +271,14 @@ namespace DbMaker
eptr = HeaderPtr[m + 1]; eptr = HeaderPtr[m + 1];
break; break;
} }
else if (ip > HeaderSip[m - 1])
if (ip > HeaderSip[m - 1])
{ {
sptr = HeaderPtr[m - 1]; sptr = HeaderPtr[m - 1];
eptr = HeaderPtr[m]; eptr = HeaderPtr[m];
break; break;
} }
h = m - 1; h = m - 1;
} }
else else
@ -273,34 +289,40 @@ namespace DbMaker
eptr = HeaderPtr[m]; eptr = HeaderPtr[m];
break; break;
} }
else if (ip <= HeaderSip[m + 1])
if (ip <= HeaderSip[m + 1])
{ {
sptr = HeaderPtr[m]; sptr = HeaderPtr[m];
eptr = HeaderPtr[m + 1]; eptr = HeaderPtr[m + 1];
break; break;
} }
l = m + 1; l = m + 1;
} }
} }
//match nothing just stop it //match nothing just stop it
if (sptr == 0) return null; if (sptr == 0)
{
return null;
}
//2. search the index blocks to define the data //2. search the index blocks to define the data
int blockLen = eptr - sptr, blen = IndexBlock.GetIndexBlockLength(); int blockLen = eptr - sptr, blen = IndexBlock.GetIndexBlockLength();
byte[] var
iBuffer = new byte[blockLen + blen]; //include the right border block iBuffer = new byte[blockLen + blen]; //include the right border block
//raf.seek(sptr); //raf.seek(sptr);
//raf.readFully(iBuffer, 0, iBuffer.length); //raf.readFully(iBuffer, 0, iBuffer.length);
raf.Seek(sptr, SeekOrigin.Begin); raf.Seek(sptr, SeekOrigin.Begin);
raf.Read(iBuffer, 0, iBuffer.Length); raf.Read(iBuffer, 0, iBuffer.Length);
l = 0; h = blockLen / blen; l = 0;
h = blockLen / blen;
long sip, eip, dataptr = 0; long sip, eip, dataptr = 0;
while (l <= h) while (l <= h)
{ {
int m = (l + h) >> 1; var m = l + h >> 1;
int p = m * blen; var p = m * blen;
sip = Util.getIntLong(iBuffer, p); sip = Util.getIntLong(iBuffer, p);
if (ip < sip) if (ip < sip)
{ {
@ -322,18 +344,21 @@ namespace DbMaker
} }
//not matched //not matched
if (dataptr == 0) return null; if (dataptr == 0)
{
return null;
}
//3. get the data //3. get the data
int dataLen = (int)((dataptr >> 24) & 0xFF); var dataLen = (int) (dataptr >> 24 & 0xFF);
int dataPtr = (int)((dataptr & 0x00FFFFFF)); var dataPtr = (int) (dataptr & 0x00FFFFFF);
//raf.seek(dataPtr); //raf.seek(dataPtr);
byte[] data = new byte[dataLen]; var data = new byte[dataLen];
// raf.readFully(data, 0, data.length); // raf.readFully(data, 0, data.length);
raf.Seek(dataPtr, SeekOrigin.Begin); raf.Seek(dataPtr, SeekOrigin.Begin);
raf.Read(data, 0, data.Length); raf.Read(data, 0, data.Length);
int city_id = (int)Util.getIntLong(data, 0); var city_id = (int) Util.getIntLong(data, 0);
//String region = new String(data, 4, data.length - 4, "UTF-8"); //String region = new String(data, 4, data.length - 4, "UTF-8");
var region = Encoding.UTF8.GetString(data, 4, data.Length - 4); var region = Encoding.UTF8.GetString(data, 4, data.Length - 4);
return new DataBlock(city_id, region, dataPtr); return new DataBlock(city_id, region, dataPtr);
@ -344,43 +369,43 @@ namespace DbMaker
* *
* @param ip * @param ip
* @return DataBlock * @return DataBlock
* @throws IOException * @throws IOException
*/ */
public DataBlock btreeSearch(String ip) public DataBlock BTreeSearch(string ip)
{ {
return btreeSearch(Util.ip2long(ip)); return BTreeSearch(Util.ip2long(ip));
} }
/** /**
* get the region with a int ip address with binary search algorithm * get the region with a int ip address with binary search algorithm
* *
* @param ip * @param ip
* @throws IOException * @throws IOException
*/ */
public DataBlock binarySearch(long ip) public DataBlock BinarySearch(long ip)
{ {
int blen = IndexBlock.GetIndexBlockLength(); var blen = IndexBlock.GetIndexBlockLength();
if (totalIndexBlocks == 0) if (totalIndexBlocks == 0)
{ {
//raf.seek(0L); //raf.seek(0L);
byte[] superBytes = new byte[8]; var superBytes = new byte[8];
//raf.readFully(superBytes, 0, superBytes.length); //raf.readFully(superBytes, 0, superBytes.length);
raf.Seek(0, SeekOrigin.Begin); raf.Seek(0, SeekOrigin.Begin);
raf.Read(superBytes, 0, superBytes.Length); raf.Read(superBytes, 0, superBytes.Length);
//initialize the global vars //initialize the global vars
firstIndexPtr = Util.getIntLong(superBytes, 0); firstIndexPtr = Util.getIntLong(superBytes, 0);
lastIndexPtr = Util.getIntLong(superBytes, 4); lastIndexPtr = Util.getIntLong(superBytes, 4);
totalIndexBlocks = (int)((lastIndexPtr - firstIndexPtr) / blen) + 1; totalIndexBlocks = (int) ((lastIndexPtr - firstIndexPtr) / blen) + 1;
} }
//search the index blocks to define the data //search the index blocks to define the data
int l = 0, h = totalIndexBlocks; int l = 0, h = totalIndexBlocks;
byte[] var
buffer = new byte[blen]; buffer = new byte[blen];
long sip, eip, dataptr = 0; long sip, eip, dataptr = 0;
while (l <= h) while (l <= h)
{ {
int m = (l + h) >> 1; var m = l + h >> 1;
//raf.seek(firstIndexPtr + m * blen); //set the file pointer //raf.seek(firstIndexPtr + m * blen); //set the file pointer
//raf.readFully(buffer, 0, buffer.length); //raf.readFully(buffer, 0, buffer.length);
raf.Seek(firstIndexPtr + m * blen, SeekOrigin.Begin); raf.Seek(firstIndexPtr + m * blen, SeekOrigin.Begin);
@ -406,19 +431,22 @@ namespace DbMaker
} }
//not matched //not matched
if (dataptr == 0) return null; if (dataptr == 0)
{
return null;
}
//get the data //get the data
int dataLen = (int)((dataptr >> 24) & 0xFF); var dataLen = (int) (dataptr >> 24 & 0xFF);
int dataPtr = (int)((dataptr & 0x00FFFFFF)); var dataPtr = (int) (dataptr & 0x00FFFFFF);
//raf.seek(dataPtr); //raf.seek(dataPtr);
byte[] data = new byte[dataLen]; var data = new byte[dataLen];
//raf.readFully(data, 0, data.length); //raf.readFully(data, 0, data.length);
raf.Seek(dataPtr, SeekOrigin.Begin); raf.Seek(dataPtr, SeekOrigin.Begin);
raf.Read(data, 0, data.Length); raf.Read(data, 0, data.Length);
int city_id = (int)Util.getIntLong(data, 0); var city_id = (int) Util.getIntLong(data, 0);
//String region = new String(data, 4, data.length - 4, "UTF-8"); //String region = new String(data, 4, data.length - 4, "UTF-8");
var region = Encoding.UTF8.GetString(data, 4, data.Length - 4); var region = Encoding.UTF8.GetString(data, 4, data.Length - 4);
return new DataBlock(city_id, region, dataPtr); return new DataBlock(city_id, region, dataPtr);
@ -429,34 +457,25 @@ namespace DbMaker
* *
* @param ip * @param ip
* @return DataBlock * @return DataBlock
* @throws IOException * @throws IOException
*/ */
public DataBlock binarySearch(String ip) public DataBlock BinarySearch(string ip)
{ {
return binarySearch(Util.ip2long(ip)); return BinarySearch(Util.ip2long(ip));
} }
/**
* get the db config
*
* @return DbConfig
*/
public DbConfig getDbConfig()
{
return dbConfig;
}
/** /**
* close the db * close the db
* *
* @throws IOException * @throws IOException
*/ */
public void close() private void Close()
{ {
HeaderSip = null; //let gc do its work HeaderSip = null; //let gc do its work
HeaderPtr = null; HeaderPtr = null;
dbBinStr = null; dbBinStr = null;
raf.Close(); raf?.Close();
} }
} }
} }

View File

@ -6,6 +6,13 @@ namespace DbMaker
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
var fn = @"G:\src\ip2region\data\ip2region.db";
using (var searcher = new DbSearcher(new DbConfig(), fn))
{
Console.WriteLine(searcher.BinarySearch("202.102.227.68"));
Console.WriteLine(searcher.BTreeSearch("202.102.227.68"));
Console.ReadLine();
}
} }
} }
} }