mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
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 的支持):
|
||||
1. [https://github.com/zoujingli/ip2region](https://github.com/zoujingli/ip2region)
|
||||
第三方 composer 地址:
|
||||
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)
|
||||
|
||||
|
||||
@ -24,6 +24,23 @@ $version = IPv6::default();
|
||||
// 备注:以下演示直接使用 $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
|
||||
// require or autoload the xdb\Searcher
|
||||
|
||||
@ -70,6 +70,16 @@ if ($handle === false) {
|
||||
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
|
||||
$header = Util::loadHeader($handle);
|
||||
if ($header == null) {
|
||||
|
||||
@ -66,6 +66,16 @@ if ($handle === false) {
|
||||
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
|
||||
$header = Util::loadHeader($handle);
|
||||
if ($header == null) {
|
||||
|
||||
@ -126,6 +126,57 @@ class Util {
|
||||
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
|
||||
public static function loadHeader($handle) {
|
||||
if (fseek($handle, 0) == -1) {
|
||||
@ -473,11 +524,6 @@ class Searcher {
|
||||
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) {
|
||||
$h = $m - 1;
|
||||
} else if ($this->version->ipSubCompare($ipBytes, $buff, $bytes) > 0) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user