verify impl and verify the xdb files

This commit is contained in:
lion 2025-10-13 22:21:30 +08:00
parent e073e26f52
commit 2dcccf22a3
4 changed files with 66 additions and 6 deletions

View File

@ -22,7 +22,7 @@ let version = IPv6;
### 文件验证 ### 文件验证
建议您主动去验证 xdb 文件的适用性,因为后期的一些新功能可能会导致目前的 Searcher 版本无法适用你使用的 xdb 文件,验证可以避免运行过程中的一些不可预测的错误。 你不需要每次都去验证,例如在服务启动的时候,或者手动调用命令验证确认版本匹配即可,不要在每次创建的 Searcher 的时候运行验证,这样会影响查询的响应速度,尤其是高并发的使用场景。 建议您主动去验证 xdb 文件的适用性,因为后期的一些新功能可能会导致目前的 Searcher 版本无法适用你使用的 xdb 文件,验证可以避免运行过程中的一些不可预测的错误。 你不需要每次都去验证,例如在服务启动的时候,或者手动调用命令验证确认版本匹配即可,不要在每次创建的 Searcher 的时候运行验证,这样会影响查询的响应速度,尤其是高并发的使用场景。
```javascript ```javascript
import verifyFomFile from './index.js'; import verifyFromFile from './index.js';
try { try {
verifyFromFile(dbPath); verifyFromFile(dbPath);
@ -30,6 +30,7 @@ try {
// 适用性验证失败!!! // 适用性验证失败!!!
// 当前查询客户端实现不适用于 dbPath 指定的 xdb 文件的查询. // 当前查询客户端实现不适用于 dbPath 指定的 xdb 文件的查询.
// 应该停止启动服务,使用合适的 xdb 文件或者升级到适合 dbPath 的 Searcher 实现。 // 应该停止启动服务,使用合适的 xdb 文件或者升级到适合 dbPath 的 Searcher 实现。
console.log(`binding is not applicable for xdb file '${dbPath}': ${e.message}`);
return; return;
} }

View File

@ -30,7 +30,9 @@ export {
loadVectorIndex, loadVectorIndex,
loadVectorIndexFromFile, loadVectorIndexFromFile,
loadContent, loadContent,
loadContentFromFile loadContentFromFile,
verify,
verifyFromFile
} from './util.js'; } from './util.js';
export { export {

View File

@ -5,7 +5,7 @@
// searcher search tester // searcher search tester
// @Author Lion <chenxin619315@gmail.com> // @Author Lion <chenxin619315@gmail.com>
import {IPv4, IPv6, parseIP, ipToString, newWithFileOnly} from '../index.js'; import {IPv4, IPv6, parseIP, ipToString, newWithFileOnly, verifyFromFile} from '../index.js';
import path from 'path'; import path from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
@ -16,6 +16,18 @@ const dbPath = {
} }
test('ipv4 search test', async () => { test('ipv4 search test', async () => {
// 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 verify function for details.
try {
verifyFromFile(dbPath.v4);
console.log(`xdb file '${dbPath.v4}' verified`);
} catch (e) {
console.log(`binding is not applicable for xdb file '${dbPath.v4}': ${e.message}`);
return;
}
let searcher = newWithFileOnly(IPv4, dbPath.v4); let searcher = newWithFileOnly(IPv4, dbPath.v4);
let ip_list = [ let ip_list = [
'1.0.0.0', '1.0.0.0',
@ -38,6 +50,18 @@ test('ipv4 search test', async () => {
}); });
test('ipv6 search test', async () => { test('ipv6 search test', async () => {
// 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 verify function for details.
try {
verifyFromFile(dbPath.v6);
console.log(`xdb file '${dbPath.v6}' verified`);
} catch (e) {
console.log(`binding is not applicable for xdb file '${dbPath.v6}': ${e.message}`);
return;
}
let searcher = newWithFileOnly(IPv6, dbPath.v6); let searcher = newWithFileOnly(IPv6, dbPath.v6);
let ip_list = [ let ip_list = [
'2a02:26f7:c409:4001::', '2a02:26f7:c409:4001::',

View File

@ -373,9 +373,42 @@ export function loadContent(fd) {
export function loadContentFromFile(dbPath) { export function loadContentFromFile(dbPath) {
const fd = fs.openSync(dbPath, "r"); const fd = fs.openSync(dbPath, "r");
const content = loadContent(fd); const content = loadContent(fd);
fs.close(fd, function(){}); fs.closeSync(fd);
return content; return content;
} }
const ipBytes = parseIP("2a02:26f7:c409:4001::"); // ---
console.log(ipToString(ipBytes));
// 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.
export function verify(fd) {
const header = loadHeader(fd);
// get the runtime ptr bytes
let runtimePtrBytes = 0;
if (header.version == XdbStructure20) {
runtimePtrBytes = 4;
} else if (header.version == XdbStructure30) {
runtimePtrBytes = header.runtimePtrBytes;
} else {
throw new Error(`invalid structure version ${header.version}`);
}
// 1, confirm the xdb file size
// to ensure that the maximum file pointer does not overflow
const maxFilePtr = (1n << BigInt(runtimePtrBytes * 8)) - 1n;
const _fileBytes = BigInt(fs.fstatSync(fd).size);
if (_fileBytes > maxFilePtr) {
throw new Error(`xdb file exceeds the maximum supported bytes: ${maxFilePtr}`);
}
}
export function verifyFromFile(dbPath) {
const fd = fs.openSync(dbPath, "r");
verify(fd);
fs.closeSync(fd);
}