pure lua script is ready for IPv6
This commit is contained in:
parent
6cb1da2794
commit
541420b8df
|
|
@ -5,30 +5,49 @@
|
||||||
|
|
||||||
# 使用方式
|
# 使用方式
|
||||||
|
|
||||||
|
### 关于 IPv4 和 IPv6
|
||||||
|
```lua
|
||||||
|
local xdb = require("xdb_searcher")
|
||||||
|
|
||||||
|
-- 如果是 IPv4: 设置 xdb 路径为 v4 的 xdb 文件,IP版本指定为 Version.IPv4
|
||||||
|
local dbPath = "../../data/ip2region_v4.xdb" -- 或者你的 ipv4 xdb 的路径
|
||||||
|
local version = xdb.IPv4
|
||||||
|
|
||||||
|
-- 如果是 IPv6: 设置 xdb 路径为 v6 的 xdb 文件,IP版本指定为 Version.IPv6
|
||||||
|
local dbPath = "../../data/ip2region_v6.xdb" -- 或者你的 ipv6 xdb 路径
|
||||||
|
local version = xdb.IPv6
|
||||||
|
|
||||||
|
-- dbPath 指定的 xdb 的 IP 版本必须和 version 指定的一致,不然查询执行的时候会报错
|
||||||
|
-- 备注:以下演示直接使用 dbPath 和 version 变量
|
||||||
|
```
|
||||||
|
|
||||||
### 完全基于文件的查询
|
### 完全基于文件的查询
|
||||||
```lua
|
```lua
|
||||||
local xdb = require("xdb_searcher")
|
local xdb = require("xdb_searcher")
|
||||||
|
|
||||||
-- 1、从 db_path 创建基于文件的 xdb 查询对象
|
-- 1,使用上述的 version 和 dbPath 创建完全基于文件的查询对象
|
||||||
local db_path = "ip2region.xdb file path"
|
local searcher, err = xdb.new_with_file_only(version, db_path)
|
||||||
local searcher, err = xdb.new_with_file_only(db_path)
|
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to create searcher: %s", err))
|
print(string.format("failed to create searcher: %s", err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 2、调用查询 API 进行查询
|
-- 2、调用查询 API 进行查询,IPv4 或者 IPv6 的地址都是同一个接口
|
||||||
local ip_str = "1.2.3.4"
|
local ip_str = "1.2.3.4"
|
||||||
|
-- local ip_str = "240e:3b7:3272:d8d0:db09:c067:8d59:539e" -- IPv6
|
||||||
local s_time = xdb.now()
|
local s_time = xdb.now()
|
||||||
region, err = searcher:search(ip_str)
|
region, err = searcher:search_by_string(ip_str)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to search(%s): %s", ip_str, err))
|
print(string.format("failed to search(%s): %s", ip_str, err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 备注:并发使用,每个协程需要创建单独的 xdb 查询对象
|
print(string.format("{region: %s, io_count: %d, took: %.5f μs}", region, searcher:get_io_count(), xdb.now() - s_time))
|
||||||
|
|
||||||
print(string.format("{region: %s, took: %.5f μs}", region, xdb.now() - s_time))
|
-- 3、关闭资源
|
||||||
|
searcher:close()
|
||||||
|
|
||||||
|
-- 备注:并发使用,每个协程需要创建单独的 xdb 查询对象
|
||||||
```
|
```
|
||||||
|
|
||||||
### 缓存 `VectorIndex` 索引
|
### 缓存 `VectorIndex` 索引
|
||||||
|
|
@ -37,35 +56,37 @@ print(string.format("{region: %s, took: %.5f μs}", region, xdb.now() - s_time))
|
||||||
```lua
|
```lua
|
||||||
local xdb = require("xdb_searcher")
|
local xdb = require("xdb_searcher")
|
||||||
|
|
||||||
local db_path = "ip2region.xdb file path"
|
-- 1、从指定的 db_path 加载 vectorIndex 缓存,把下述的 v_index 对象做成全局变量。
|
||||||
|
|
||||||
-- 1、从指定的 db_path 加载 VectorIndex 缓存,把下述的 v_index 对象做成全局变量。
|
|
||||||
-- vectorIndex 加载一次即可,建议在服务启动的时候加载为全局对象。
|
-- vectorIndex 加载一次即可,建议在服务启动的时候加载为全局对象。
|
||||||
v_index, err = xdb.load_vector_index(db_path)
|
v_index, err = xdb.load_vector_index(dbPath)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to load vector index from '%s'", db_path))
|
print(string.format("failed to load vector index from '%s'", db_path))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 2、使用全局的 v_index 创建带 VectorIndex 缓存的查询对象。
|
-- 2、使用全局的 v_index 创建带 vectorIndex 缓存的查询对象。
|
||||||
searcher, err = xdb.new_with_vector_index(db_path, v_index)
|
searcher, err = xdb.new_with_vector_index(version, dbPath, v_index)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to create vector index searcher: %s", err))
|
print(string.format("failed to create vector index searcher: %s", err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 3、调用查询 API
|
-- 3、调用查询 API,IPv4 或者 IPv6 都是同一个接口
|
||||||
local ip_str = "1.2.3.4"
|
local ip_str = "1.2.3.4"
|
||||||
|
-- local ip_str = "240e:3b7:3272:d8d0:db09:c067:8d59:539e" -- IPv6
|
||||||
local s_time = xdb.now()
|
local s_time = xdb.now()
|
||||||
region, err = searcher:search(ip_str)
|
region, err = searcher:search_by_string(ip_str)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to search(%s): %s", ip_str, err))
|
print(string.format("failed to search(%s): %s", ip_str, err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 备注:并发使用,每个协程需要创建单独的 xdb 查询对象,但是共享全局的 v_index 对象
|
print(string.format("{region: %s, io_count: %d, took: %.5f μs}", region, searcher:get_io_count(), xdb.now() - s_time))
|
||||||
|
|
||||||
print(string.format("{region: %s, took: %.5f μs}", region, xdb.now() - s_time))
|
-- 4、关闭资源
|
||||||
|
searcher:close()
|
||||||
|
|
||||||
|
-- 备注:并发使用,每个协程需要创建单独的 xdb 查询对象,但是共享全局的 v_index 对象
|
||||||
```
|
```
|
||||||
|
|
||||||
### 缓存整个 `xdb` 数据
|
### 缓存整个 `xdb` 数据
|
||||||
|
|
@ -74,58 +95,70 @@ print(string.format("{region: %s, took: %.5f μs}", region, xdb.now() - s_time))
|
||||||
```lua
|
```lua
|
||||||
local xdb = require("xdb_searcher")
|
local xdb = require("xdb_searcher")
|
||||||
|
|
||||||
local db_path = "ip2region.xdb file path"
|
-- 1、从上述的 dbPath 加载整个 xdb 到内存。
|
||||||
|
|
||||||
-- 1、从指定的 db_path 加载整个 xdb 到内存。
|
|
||||||
-- xdb内容加载一次即可,建议在服务启动的时候加载为全局对象。
|
-- xdb内容加载一次即可,建议在服务启动的时候加载为全局对象。
|
||||||
content = xdb.load_content(db_path)
|
content, err = xdb.load_content(dbPath)
|
||||||
if content == nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to load xdb content from '%s'", db_path))
|
print(string.format("failed to load xdb content: %s", err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 2、使用全局的 content 创建带完全基于内存的查询对象。
|
-- 2、使用全局的 content 创建带完全基于内存的查询对象。
|
||||||
searcher, err = xdb.new_with_buffer(content)
|
searcher, err = xdb.new_with_buffer(version, content)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to create content buffer searcher: %s", err))
|
print(string.format("failed to create content buffer searcher: %s", err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 3、调用查询 API
|
-- 3、调用查询 API,IPv4 或者 IPv6 都是同一个接口
|
||||||
local ip_str = "1.2.3.4"
|
local ip_str = "1.2.3.4"
|
||||||
|
-- local ip_str = "240e:3b7:3272:d8d0:db09:c067:8d59:539e" -- IPv6
|
||||||
local s_time = xdb.now()
|
local s_time = xdb.now()
|
||||||
region, err = searcher:search(ip_str)
|
region, err = searcher:search_by_string(ip_str)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to search(%s): %s", ip_str, err))
|
print(string.format("failed to search(%s): %s", ip_str, err))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
print(string.format("{region: %s, io_count: %d, took: %.5f μs}", region, searcher:get_io_count(), xdb.now() - s_time))
|
||||||
|
|
||||||
|
-- 4、关闭资源 - 该 searcher 对象可以安全用于并发,等整个服务关闭的时候再关闭 searcher
|
||||||
|
-- searcher:close()
|
||||||
|
|
||||||
-- 备注:并发使用,用 xdb 整个缓存创建的查询对象可以安全的用于并发。
|
-- 备注:并发使用,用 xdb 整个缓存创建的查询对象可以安全的用于并发。
|
||||||
-- 建议在服务启动的时候创建好全局的 searcher 对象,然后全局并发使用。
|
-- 建议在服务启动的时候创建好全局的 searcher 对象,然后全局并发使用。
|
||||||
|
|
||||||
print(string.format("{region: %s, took: %.5f μs}", region, xdb.now() - s_time))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
# 查询测试
|
# 查询测试
|
||||||
|
|
||||||
通过 `search_test.lua` 脚本来进行查询测试:
|
通过 `lua search_test.lua` 脚本来进行查询测试:
|
||||||
```bash
|
```bash
|
||||||
➜ lua git:(lua_binding) ✗ lua search_test.lua
|
➜ lua git:(fr_lua_ipv6) ✗ lua search_test.lua
|
||||||
lua search_test.lua [command options]
|
lua search_test.lua [command options]
|
||||||
options:
|
options:
|
||||||
--db string ip2region binary xdb file path
|
--db string ip2region binary xdb file path
|
||||||
--cache-policy string cache policy: file/vectorIndex/content
|
--cache-policy string cache policy: file/vectorIndex/content
|
||||||
```
|
```
|
||||||
|
|
||||||
例如:使用默认的 data/ip2region.xdb 进行查询测试:
|
例如:使用默认的 data/ip2region_v4.xdb 文件进行 IPv4 的查询测试:
|
||||||
```bash
|
```bash
|
||||||
➜ lua git:(lua_binding) ✗ lua search_test.lua --db=../../data/ip2region.xdb --cache-policy=vectorIndex
|
➜ lua git:(fr_lua_ipv6) ✗ lua search_test.lua --db=../../data/ip2region_v4.xdb
|
||||||
ip2region xdb searcher test program, cachePolicy: vectorIndex
|
ip2region xdb searcher test program
|
||||||
|
source xdb: ../../data/ip2region_v4.xdb (IPv4, vectorIndex)
|
||||||
type 'quit' to exit
|
type 'quit' to exit
|
||||||
ip2region>> 1.2.3.4
|
ip2region>> 1.2.3.4
|
||||||
{region: 美国|0|华盛顿|0|谷歌, io_count: 7, took: 0μs}
|
{region: 美国|华盛顿|0|谷歌, io_count: 7, took: 0μs}
|
||||||
ip2region>>
|
```
|
||||||
|
|
||||||
|
例如:使用默认的 data/ip2region_v6.xdb 文件进行 IPv6 的查询测试:
|
||||||
|
```bash
|
||||||
|
➜ lua git:(fr_lua_ipv6) ✗ lua search_test.lua --db=../../data/ip2region_v6.xdb
|
||||||
|
ip2region xdb searcher test program
|
||||||
|
source xdb: ../../data/ip2region_v6.xdb (IPv6, vectorIndex)
|
||||||
|
type 'quit' to exit
|
||||||
|
ip2region>> 240e:3b7:3272:d8d0:db09:c067:8d59:539e
|
||||||
|
{region: 中国|广东省|深圳市|家庭宽带, io_count: 8, took: 0μs}
|
||||||
```
|
```
|
||||||
|
|
||||||
输入 ip 即可进行查询测试。也可以分别设置 `cache-policy` 为 file/vectorIndex/content 来测试三种不同缓存实现的效率。
|
输入 ip 即可进行查询测试。也可以分别设置 `cache-policy` 为 file/vectorIndex/content 来测试三种不同缓存实现的效率。
|
||||||
|
|
@ -133,9 +166,9 @@ ip2region>>
|
||||||
|
|
||||||
# bench 测试
|
# bench 测试
|
||||||
|
|
||||||
通过 `bench_test.lua` 脚本来进行自动 bench 测试,一方面确保 `xdb` 文件没有错误,另一方面通过大量的查询测试平均查询性能:
|
通过 `lua bench_test.lua` 脚本来进行自动 bench 测试,一方面确保 `xdb` 文件没有错误,另一方面通过大量的查询测试平均查询性能:
|
||||||
```bash
|
```bash
|
||||||
➜ lua git:(lua_binding) ✗ lua bench_test.lua
|
➜ lua git:(fr_lua_ipv6) ✗ lua bench_test.lua
|
||||||
lua bench_test.lua [command options]
|
lua bench_test.lua [command options]
|
||||||
options:
|
options:
|
||||||
--db string ip2region binary xdb file path
|
--db string ip2region binary xdb file path
|
||||||
|
|
@ -143,10 +176,14 @@ options:
|
||||||
--cache-policy string cache policy: file/vectorIndex/content
|
--cache-policy string cache policy: file/vectorIndex/content
|
||||||
```
|
```
|
||||||
|
|
||||||
例如:通过默认的 data/ip2region.xdb 和 data/ip.merge.txt 来进行 bench 测试:
|
例如:通过默认的 data/ip2region_v4.xdb 和 data/ipv4_source.txt 文件进行 IPv4 的 bench 测试:
|
||||||
```bash
|
```bash
|
||||||
➜ lua git:(lua_binding) ✗ lua bench_test.lua --db=../../data/ip2region.xdb --src=../../data/ip.merge.txt --cache-policy=vectorIndex
|
lua bench_test.lua --db=../../data/ip2region_v4.xdb --src=../../data/ipv4_source.txt
|
||||||
Bench finished, {cachePolicy: vectorIndex, total: 3417955, took: 29.000 s, cost: 7.899 μs/op}
|
```
|
||||||
|
|
||||||
|
例如:通过默认的 data/ip2region_v6.xdb 和 data/ipv6_source.txt 文件进行 IPv6 的 bench 测试:
|
||||||
|
```bash
|
||||||
|
lua bench_test.lua --db=../../data/ip2region_v6.xdb --src=../../data/ipv6_source.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
可以通过设置 `cache-policy` 参数来分别测试 file/vectorIndex/content 三种不同的缓存实现的的性能。
|
可以通过设置 `cache-policy` 参数来分别测试 file/vectorIndex/content 三种不同的缓存实现的的性能。
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ end
|
||||||
local lines = handle:lines()
|
local lines = handle:lines()
|
||||||
local sip_str, eip_str, s_region, region = "", "", "", ""
|
local sip_str, eip_str, s_region, region = "", "", "", ""
|
||||||
local sip, mip, eip, err = 0, 0, 0, 0
|
local sip, mip, eip, err = 0, 0, 0, 0
|
||||||
local count, c_time = 0, 0, 0
|
local count, c_time = 0, 0
|
||||||
local s_time = xdb.now()
|
local s_time = xdb.now()
|
||||||
for l in lines do
|
for l in lines do
|
||||||
if string.len(l) < 1 then
|
if string.len(l) < 1 then
|
||||||
|
|
@ -135,9 +135,8 @@ for l in lines do
|
||||||
s_region = v3
|
s_region = v3
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
print('sip', sip_str, 'eip', eip_str, 'region', s_region)
|
-- print('sip', sip_str, 'eip', eip_str, 'region', s_region)
|
||||||
|
|
||||||
local t_time = xdb.now()
|
|
||||||
sip, err = xdb.parse_ip(sip_str)
|
sip, err = xdb.parse_ip(sip_str)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("invalid start ip `%s`", sip_str))
|
print(string.format("invalid start ip `%s`", sip_str))
|
||||||
|
|
@ -155,10 +154,9 @@ for l in lines do
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local t_time = xdb.now()
|
||||||
for _, ip in ipairs({sip, eip}) do
|
for _, ip in ipairs({sip, eip}) do
|
||||||
region, err = searcher:search(ip)
|
region, err = searcher:search(ip)
|
||||||
print(string.format('search(%s): %s', xdb.ip_to_string(ip), region))
|
|
||||||
c_time = c_time + xdb.now() - t_time
|
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("failed to search ip `%s`", xdb.ip_to_string(ip)))
|
print(string.format("failed to search ip `%s`", xdb.ip_to_string(ip)))
|
||||||
return
|
return
|
||||||
|
|
@ -172,6 +170,7 @@ for l in lines do
|
||||||
|
|
||||||
count = count + 1
|
count = count + 1
|
||||||
end
|
end
|
||||||
|
c_time = c_time + xdb.now() - t_time
|
||||||
|
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
|
|
@ -186,6 +185,6 @@ if count > 0 then
|
||||||
avg_costs = c_time / count
|
avg_costs = c_time / count
|
||||||
end
|
end
|
||||||
print(string.format(
|
print(string.format(
|
||||||
"Bench finished, {cachePolicy: %s, total: %d, took: %.3f s, cost: %.3f μs/op}",
|
"Bench finished, {cachePolicy: %s, total: %d, took: {total: %0.3fs, search: %0.3fs}, cost: %.3f μs/op}",
|
||||||
cachePolicy, count, total_costs, avg_costs
|
cachePolicy, count, total_costs, c_time/1e6, avg_costs
|
||||||
))
|
))
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ function printHelp()
|
||||||
print(" --cache-policy string cache policy: file/vectorIndex/content")
|
print(" --cache-policy string cache policy: file/vectorIndex/content")
|
||||||
end
|
end
|
||||||
|
|
||||||
if #arg < 2 then
|
if #arg < 1 then
|
||||||
printHelp(arg)
|
printHelp(arg)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -111,31 +111,36 @@ end
|
||||||
|
|
||||||
-- do the search
|
-- do the search
|
||||||
print(string.format([[
|
print(string.format([[
|
||||||
ip2region xdb searcher test program, cachePolicy: %s
|
ip2region xdb searcher test program
|
||||||
type 'quit' to exit]], cachePolicy))
|
source xdb: %s (%s, %s)
|
||||||
|
type 'quit' to exit]], dbFile, version.name, cachePolicy))
|
||||||
local region, err = "", nil
|
local region, err = "", nil
|
||||||
local ip_int, s_time, c_time = 0, 0, 0
|
local ip_bytes, s_time, c_time = nil, 0, 0
|
||||||
while ( true ) do
|
while true do
|
||||||
io.write("ip2region>> ");
|
io.write("ip2region>> ");
|
||||||
io.input(io.stdin);
|
io.input(io.stdin);
|
||||||
local line = io.read();
|
local line = io.read();
|
||||||
if (line == nil) then
|
if line == nil then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
if ( line == "quit" ) then
|
if #line < 1 then
|
||||||
|
goto continue
|
||||||
|
end
|
||||||
|
|
||||||
|
if line == "quit" then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
ip_int, err = xdb.check_ip(line)
|
s_time = xdb.now()
|
||||||
|
ip_bytes, err = xdb.parse_ip(line)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("invalid ip address `%s`", line))
|
print(string.format("failed to parse ip `%s`: %s", line, err))
|
||||||
goto continue
|
goto continue
|
||||||
end
|
end
|
||||||
|
|
||||||
-- do the search
|
-- do the search
|
||||||
s_time = xdb.now()
|
region, err = searcher:search(ip_bytes)
|
||||||
region, err = searcher:search(line)
|
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
print(string.format("{err: %s, io_count: %d}", err, searcher:get_io_count()))
|
print(string.format("{err: %s, io_count: %d}", err, searcher:get_io_count()))
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,6 @@ function xdb:search(ip_bytes)
|
||||||
-- binary search to get the data
|
-- binary search to get the data
|
||||||
local index_size, ip_sub_compare = version.index_size, version.ip_sub_compare
|
local index_size, ip_sub_compare = version.index_size, version.ip_sub_compare
|
||||||
local bytes, d_bytes = version.bytes, version.bytes << 1
|
local bytes, d_bytes = version.bytes, version.bytes << 1
|
||||||
print("index_size", index_size, "bytes", bytes, "d_bytes", d_bytes)
|
|
||||||
local data_ptr, data_len, p = 0, 0, 0
|
local data_ptr, data_len, p = 0, 0, 0
|
||||||
local sip, eip, err, buff = 0, 0, ""
|
local sip, eip, err, buff = 0, 0, ""
|
||||||
local l, m, h = 0, 0, (e_ptr - s_ptr) / index_size
|
local l, m, h = 0, 0, (e_ptr - s_ptr) / index_size
|
||||||
|
|
@ -146,13 +145,6 @@ function xdb:search(ip_bytes)
|
||||||
return "", string.format("read segment index at %d", p)
|
return "", string.format("read segment index at %d", p)
|
||||||
end
|
end
|
||||||
|
|
||||||
print(string.format(
|
|
||||||
"{ip=%s, sip=%s, eip=%s}",
|
|
||||||
xdb.ip_to_string(ip_bytes),
|
|
||||||
xdb.ip_to_string(string.sub(buff, 1, bytes)),
|
|
||||||
xdb.ip_to_string(string.sub(buff, bytes + 1, d_bytes))
|
|
||||||
))
|
|
||||||
|
|
||||||
-- check the index
|
-- check the index
|
||||||
if ip_sub_compare(ip_bytes, buff, 1) < 0 then
|
if ip_sub_compare(ip_bytes, buff, 1) < 0 then
|
||||||
h = m - 1
|
h = m - 1
|
||||||
|
|
@ -166,7 +158,7 @@ function xdb:search(ip_bytes)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- matching nothing interception
|
-- matching nothing interception
|
||||||
print(string.format("data_len=%d, data_ptr=%d", data_len, data_ptr))
|
-- print(string.format("data_len=%d, data_ptr=%d", data_len, data_ptr))
|
||||||
if data_len == 0 then
|
if data_len == 0 then
|
||||||
return "", nil
|
return "", nil
|
||||||
end
|
end
|
||||||
|
|
@ -208,6 +200,10 @@ function xdb:read(offset, length)
|
||||||
return buff, nil
|
return buff, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function xdb:get_ip_version()
|
||||||
|
return self.version
|
||||||
|
end
|
||||||
|
|
||||||
function xdb:get_io_count()
|
function xdb:get_io_count()
|
||||||
return self.io_count
|
return self.io_count
|
||||||
end
|
end
|
||||||
|
|
@ -533,7 +529,7 @@ end
|
||||||
--
|
--
|
||||||
-- ip bytes compare
|
-- ip bytes compare
|
||||||
function xdb.ip_sub_compare(ip1, buff, offset)
|
function xdb.ip_sub_compare(ip1, buff, offset)
|
||||||
local ip2 = string.sub(buff, offset, offset + #ip1)
|
local ip2 = string.sub(buff, offset, offset + #ip1 - 1)
|
||||||
if ip1 > ip2 then
|
if ip1 > ip2 then
|
||||||
return 1
|
return 1
|
||||||
elseif ip1 < ip2 then
|
elseif ip1 < ip2 then
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue