xdb searcher util and tests

This commit is contained in:
Lion 2022-06-22 17:36:01 +08:00
parent b08e798e27
commit bf0f413a22
2 changed files with 165 additions and 14 deletions

View File

@ -28,6 +28,32 @@ class XdbSearcher
// xdb content buffer
private $contentBuff = null;
// ---
// static function to create searcher
/**
* @throws Exception
*/
public static function newWithFileOnly($dbFile) {
return new XdbSearcher($dbFile, null, null);
}
/**
* @throws Exception
*/
public static function newWithVectorIndex($dbFile, $vIndex) {
return new XdbSearcher($dbFile, $vIndex);
}
/**
* @throws Exception
*/
public static function newWithBuffer($cBuff) {
return new XdbSearcher(null, null, $cBuff);
}
// --- End of static creator
/**
* initialize the xdb searcher
* @throws Exception
@ -84,7 +110,6 @@ class XdbSearcher
$il0 = ($ip >> 24) & 0xFF;
$il1 = ($ip >> 16) & 0xFF;
$idx = $il0 * self::VectorIndexRows * self::VectorIndexSize + $il1 * self::VectorIndexSize;
printf("il0: %d, il1: %d, idx: %d\n", $il0, $il1, $idx);
if ($this->vectorIndex != null) {
$sPtr = self::getLong($this->vectorIndex, $idx);
$ePtr = self::getLong($this->vectorIndex, $idx + 4);
@ -99,7 +124,7 @@ class XdbSearcher
$ePtr = self::getLong($buff, 4);
}
printf("sPtr: %d, ePtr: %d\n", $sPtr, $ePtr);
// printf("sPtr: %d, ePtr: %d\n", $sPtr, $ePtr);
// binary search the segment index to get the region info
$dataLen = 0;
@ -125,7 +150,7 @@ class XdbSearcher
$l = $m + 1;
} else {
$dataLen = self::getShort($buff, 8);
$dataPtr = self::getShort($buff, 10);
$dataPtr = self::getLong($buff, 10);
break;
}
}
@ -133,7 +158,7 @@ class XdbSearcher
// match nothing interception.
// @TODO: could this even be a case ?
printf("dataLen: %d, dataPtr: %d\n", $dataLen, $dataPtr);
// printf("dataLen: %d, dataPtr: %d\n", $dataLen, $dataPtr);
if ($dataPtr == null) {
return null;
}
@ -144,12 +169,7 @@ class XdbSearcher
return null;
}
$str = [];
foreach (unpack("C*", $buff) as $chr) {
$str[] = chr($chr);
}
return implode($str);
return $buff;
}
// read specified bytes from the specified index
@ -178,6 +198,8 @@ class XdbSearcher
return $buff;
}
// --- static util functions ----
// convert a string ip to long
public static function ip2long($ip)
{
@ -214,4 +236,108 @@ class XdbSearcher
return ((ord($b[$idx])) | (ord($b[$idx+1]) << 8));
}
// load header info from a specified file handle
public static function loadHeader($handle) {
if (fseek($handle, 0) == -1) {
return null;
}
$buff = fread($handle, self::HeaderInfoLength);
if ($buff === false) {
return null;
}
// read bytes length checking
if (strlen($buff) != self::HeaderInfoLength) {
return null;
}
// return the decoded header info
return array(
'version' => self::getShort($buff, 0),
'indexPolicy' => self::getShort($buff, 2),
'createdAt' => self::getLong($buff, 4),
'startIndexPtr' => self::getLong($buff, 8),
'endIndexPtr' => self::getLong($buff, 12)
);
}
// load header info from the specified xdb file path
public static function loadHeaderFromFile($dbFile) {
$handle = fopen($dbFile, 'r');
if ($handle === false) {
return null;
}
return self::loadHeader($handle);
}
// load vector index from a file handle
public static function loadVectorIndex($handle) {
if (fseek($handle, self::HeaderInfoLength) == -1) {
return null;
}
$rLen = self::VectorIndexRows * self::VectorIndexCols * self::SegmentIndexSize;
$buff = fread($handle, $rLen);
if ($buff === false) {
return null;
}
if (strlen($buff) != $rLen) {
return null;
}
return $buff;
}
// load vector index from a specified xdb file path
public static function loadVectorIndexFromFile($dbFile) {
$handle = fopen($dbFile, 'r');
if ($handle === false) {
return null;
}
return self::loadVectorIndex($handle);
}
// load the xdb content from a file handle
public static function loadContent($handle) {
if (fseek($handle, 0, SEEK_END) == -1) {
return null;
}
$size = ftell($handle);
if ($size === false) {
return null;
}
// seek to the head for reading
if (fseek($handle, 0) == -1) {
return null;
}
$buff = fread($handle, $size);
if ($buff === false) {
return null;
}
// read length checking
if (strlen($buff) != $size) {
return null;
}
return $buff;
}
// load the xdb content from a file path
public static function loadContentFromFile($dbFile) {
$str = file_get_contents($dbFile, false);
if ($str === false) {
return null;
} else {
return $str;
}
}
}

View File

@ -46,28 +46,52 @@ foreach ($argv as $r) {
}
}
printf("debug: dbFile: %s, cachePolicy: %s\n", $dbFile, $cachePolicy);
// printf("debug: dbFile: %s, cachePolicy: %s\n", $dbFile, $cachePolicy);
// create the xdb searcher by the cache-policy
$searcher = null;
switch ( $cachePolicy ) {
case 'file':
try {
$searcher = new XdbSearcher($dbFile);
$searcher = XdbSearcher::newWithFileOnly($dbFile);
} catch (Exception $e) {
printf("failed to create searcher with '%s': %s\n", $dbFile, $e);
return;
}
break;
case 'vectorIndex':
$vIndex = XdbSearcher::loadVectorIndexFromFile($dbFile);
if ($vIndex == null) {
printf("failed to load vector index from '%s'\n", $dbFile);
return;
}
try {
$searcher = XdbSearcher::newWithVectorIndex($dbFile, $vIndex);
} catch (Exception $e) {
printf("failed to create vector index cached searcher with '%s': %s\n", $dbFile, $e);
return;
}
break;
case 'content':
$cBuff = XdbSearcher::loadContentFromFile($dbFile);
if ($cBuff == null) {
printf("failed to load xdb content from '%s'\n", $dbFile);
return;
}
try {
$searcher = XdbSearcher::newWithBuffer($cBuff);
} catch (Exception $e) {
printf("failed to create content cached searcher: %s", $e);
return;
}
break;
default:
printf("undefined cache-policy `%s`\n", $cachePolicy);
return;
}
printf("ip2region xdb searcher test program, cachePolicy: ${cachePolicy}\ntype 'quit' to exit\n");
while ( true ) {
echo "ip2region>> ";
$line = trim(fgets(STDIN));
@ -92,11 +116,12 @@ while ( true ) {
continue;
}
printf("{region: %s, took: %.5f ms}\n", $region, getTime() - $sTime);
printf("{region: %s, ioCount: %d, took: %.5f ms}\n", $region, $searcher->getIOCount(), getTime() - $sTime);
}
// close the searcher at last
$searcher->close();
printf("searcher test program exited, thanks for trying\n");
function getTime()
{