add xdb file verify util and call it before the search/bench test
This commit is contained in:
parent
4c1b0362c8
commit
9a14e32736
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
# 使用方式
|
# 使用方式
|
||||||
|
|
||||||
第三方 composer 地址 (请自行确认仓库对 IPv6 的支持):
|
第三方 composer 地址:
|
||||||
1. [https://github.com/zoujingli/ip2region](https://github.com/zoujingli/ip2region)
|
1. [https://github.com/zoujingli/ip2region](https://github.com/zoujingli/ip2region) - 已提供 IPv6 支持。
|
||||||
2. [https://github.com/chinayin/ip2region-core-php](https://github.com/chinayin/ip2region-core-php)
|
2. [https://github.com/chinayin/ip2region-core-php](https://github.com/chinayin/ip2region-core-php)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,6 +24,23 @@ $version = IPv6::default();
|
||||||
// 备注:以下演示直接使用 $dbFile 和 $version 变量
|
// 备注:以下演示直接使用 $dbFile 和 $version 变量
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### XDB 文件验证
|
||||||
|
建议您主动去验证 xdb 文件的适用性,因为后期的一些新功能可能会导致目前的 Searcher 版本无法适用你使用的 xdb 文件,验证可以避免运行过程中的一些不可预测的错误。 你不需要每次都去验证,例如在服务启动的时候,或者手动调用命令验证确认版本匹配即可,不要在每次创建的 Searcher 的时候运行验证,这样会影响查询的响应速度,尤其是高并发的使用场景。
|
||||||
|
```php
|
||||||
|
use \ip2region\xdb\Util;
|
||||||
|
|
||||||
|
$err = Util::verify($dbFile);
|
||||||
|
if ($err != null) {
|
||||||
|
// 适用性验证失败!!!
|
||||||
|
// 当前查询客户端实现不适用于 dbPath 指定的 xdb 文件的查询.
|
||||||
|
// 应该停止启动服务,使用合适的 xdb 文件或者升级到适合 dbPath 的 Searcher 实现。
|
||||||
|
printf("failed to verify xdb file `%s`: %s\n", $dbFile, $err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证通过,当前使用的 Searcher 可以安全的用于对 dbPath 指向的 xdb 的查询操作
|
||||||
|
```
|
||||||
|
|
||||||
### 完全基于文件的查询
|
### 完全基于文件的查询
|
||||||
```php
|
```php
|
||||||
// require or autoload the xdb\Searcher
|
// require or autoload the xdb\Searcher
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,16 @@ if ($handle === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verify the xdb file
|
||||||
|
// @Note: do NOT call it every time you create a searcher since this will slow
|
||||||
|
// down the search response.
|
||||||
|
// @see the Util.verify function for details.
|
||||||
|
$err = Util::verify($handle);
|
||||||
|
if ($err != null) {
|
||||||
|
printf("failed to verify xdb file `%s`: %s\n", $dbFile, $err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// load header
|
// load header
|
||||||
$header = Util::loadHeader($handle);
|
$header = Util::loadHeader($handle);
|
||||||
if ($header == null) {
|
if ($header == null) {
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,16 @@ if ($handle === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verify the xdb file
|
||||||
|
// @Note: do NOT call it every time you create a searcher since this will slow
|
||||||
|
// down the search response.
|
||||||
|
// @see the Util.verify function for details.
|
||||||
|
$err = Util::verify($handle);
|
||||||
|
if ($err != null) {
|
||||||
|
printf("failed to verify xdb file `%s`: %s\n", $dbFile, $err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// load header
|
// load header
|
||||||
$header = Util::loadHeader($handle);
|
$header = Util::loadHeader($handle);
|
||||||
if ($header == null) {
|
if ($header == null) {
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,57 @@ class Util {
|
||||||
return ((ord($b[$idx])) | (ord($b[$idx+1]) << 8));
|
return ((ord($b[$idx])) | (ord($b[$idx+1]) << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify if the current Searcher could be used to search the specified xdb file.
|
||||||
|
// Why do we need this check ?
|
||||||
|
// The future features of the xdb impl may cause the current searcher not able to work properly.
|
||||||
|
//
|
||||||
|
// @Note: You Just need to check this ONCE when the service starts
|
||||||
|
// Or use another process (eg, A command) to check once Just to confirm the suitability.
|
||||||
|
// returns: null for everything is ok or the error string.
|
||||||
|
public static function verify($handle) {
|
||||||
|
// load the header
|
||||||
|
$header = self::loadHeader($handle);
|
||||||
|
if ($header == null) {
|
||||||
|
return 'failed to load the header';
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the runtime ptr bytes
|
||||||
|
$runtimePtrBytes = 0;
|
||||||
|
if ($header['version'] == Structure_20) {
|
||||||
|
$runtimePtrBytes = 4;
|
||||||
|
} else if ($header['version'] == Structure_30) {
|
||||||
|
$runtimePtrBytes = $header['runtimePtrBytes'];
|
||||||
|
} else {
|
||||||
|
return "invalid structure version `{$header['version']}`";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1, confirm the xdb file size
|
||||||
|
// to ensure that the maximum file pointer does not overflow
|
||||||
|
$stat = fstat($handle);
|
||||||
|
if ($stat == false) {
|
||||||
|
return 'failed to stat the xdb file';
|
||||||
|
}
|
||||||
|
|
||||||
|
$maxFilePtr = (1 << ($runtimePtrBytes * 8)) - 1;
|
||||||
|
// print_r([$stat['size'], $maxFilePtr]);
|
||||||
|
if ($stat['size'] > $maxFilePtr) {
|
||||||
|
return "xdb file exceeds the maximum supported bytes: {$maxFilePtr}";
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function verifyFromFile($dbFile) {
|
||||||
|
$handle = fopen($dbFile, 'r');
|
||||||
|
if ($handle === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = self::verify($handle);
|
||||||
|
fclose($handle);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
// load header info from a specified file handle
|
// load header info from a specified file handle
|
||||||
public static function loadHeader($handle) {
|
public static function loadHeader($handle) {
|
||||||
if (fseek($handle, 0) == -1) {
|
if (fseek($handle, 0) == -1) {
|
||||||
|
|
@ -473,11 +524,6 @@ class Searcher {
|
||||||
throw new Exception("failed to read segment index with ptr={$p}");
|
throw new Exception("failed to read segment index with ptr={$p}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("l=%d, h=%d, sip=%s, eip=%s\n",
|
|
||||||
// $l, $h,
|
|
||||||
// Util::ipToString(strrev(substr($buff, 0, 4))),
|
|
||||||
// Util::ipToString(strrev(substr($buff, 4, 4)))
|
|
||||||
// );
|
|
||||||
if ($this->version->ipSubCompare($ipBytes, $buff, 0) < 0) {
|
if ($this->version->ipSubCompare($ipBytes, $buff, 0) < 0) {
|
||||||
$h = $m - 1;
|
$h = $m - 1;
|
||||||
} else if ($this->version->ipSubCompare($ipBytes, $buff, $bytes) > 0) {
|
} else if ($this->version->ipSubCompare($ipBytes, $buff, $bytes) > 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue