191 lines
7.9 KiB
Markdown
191 lines
7.9 KiB
Markdown
:globe_with_meridians: [中文简体](README_zh.md) | [English](README.md)
|
|
|
|
## `ip2region rust` Query Client
|
|
|
|
## Features
|
|
|
|
* Supports queries using both `ip` strings and `u32`/`u28` numeric types
|
|
* Supports IPv4 and IPv6
|
|
* Supports three modes: No Cache, Vector Index Cache, and Full Data Cache
|
|
|
|
## Cache Policy Comparison and Description
|
|
|
|
| Cache Mode | IPv4 Memory Usage | IPv6 Memory Usage | IPv4 benchmark query time | IPv6 benchmark query time |
|
|
| --- | --- | --- | --- | --- |
|
|
| No Cache | 1-2MB | 1-2MB | 54 us | 122us |
|
|
| vector index | 1-2MB | 1-2MB | 27 us | 100us |
|
|
| Full Cache | 20 MB | 200 MB | 120 ns | 178 ns |
|
|
|
|
* During the initialization of `ip2region::Searcher`, an IO operation occurs to read the `xdb` header information to initialize the `Searcher`. The header information mainly includes the IP version of the `xdb`. This operation does not affect the performance or time consumption of subsequent IP queries and occupies approximately 20 additional bytes of memory.
|
|
* In No Cache mode and `vector index` cache mode, all `xdb` IO reads are performed on-demand (based on bytes offset and bytes length) for small amounts of information. Both are thread-safe, as verified by benchmark testing.
|
|
* In Full Cache mode, the `xdb` file is read and loaded into memory at once. Testing shows the `IPv6 xdb` file occupies about 200MB of memory. If queries are infrequent, memory usage will gradually decrease.
|
|
* In all cache modes, including during the initialization of `ip2region::Searcher`, the program is thread-safe. There are no globally modifiable intermediate variables. After `ip2region::Searcher` initialization is complete, calling the `search` function uses immutable references. Meanwhile, `ip2region::Searcher` can also be passed to different threads using `Arc`.
|
|
|
|
## Usage
|
|
|
|
Create a new project using `cargo`, such as `cargo new ip-test`
|
|
|
|
Configure `[dependencies]` in `Cargo.toml` as follows:
|
|
|
|
```toml
|
|
[dependencies]
|
|
ip2region = { git = "https://github.com/lionsoul2014/ip2region.git", branch = "master" }
|
|
|
|
```
|
|
|
|
### Basic Usage Example
|
|
|
|
Write `main.rs`
|
|
|
|
```rust
|
|
use ip2region::{CachePolicy, Searcher};
|
|
|
|
fn main() {
|
|
for cache_policy in [
|
|
CachePolicy::NoCache,
|
|
CachePolicy::FullMemory,
|
|
CachePolicy::VectorIndex,
|
|
] {
|
|
// Create an IPv4 searcher
|
|
let ipv4_seacher = Searcher::new("../ip2region/data/ip2region_v4.xdb".to_owned(), cache_policy).unwrap();
|
|
for ip in [1_u32, 2, 3] {
|
|
let result = ipv4_seacher.search(ip).unwrap();
|
|
println!("CachePolicy: {cache_policy:?}, IP: {ip}, Result: {result}");
|
|
}
|
|
|
|
for ip in ["1.1.1.1", "2.2.2.2"] {
|
|
let result = ipv4_seacher.search(ip).unwrap();
|
|
println!("CachePolicy: {cache_policy:?}, IP: {ip}, Result: {result}");
|
|
}
|
|
|
|
// Create an IPv6 searcher
|
|
let ipv6_seacher = Searcher::new("../ip2region/data/ip2region_v6.xdb".to_owned(), cache_policy).unwrap();
|
|
for ip in ["2001::", "2001:4:112::"] {
|
|
let result = ipv6_seacher.search(ip).unwrap();
|
|
println!("CachePolicy: {cache_policy:?}, IP: {ip}, Result: {result}");
|
|
}
|
|
|
|
for ip in [1_u128, 2, 3<<125] {
|
|
let result = ipv6_seacher.search(ip).unwrap();
|
|
println!("CachePolicy: {cache_policy:?}, IP: {ip}, Result: {result}");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Cache policy benchmark
|
|
|
|
```bash
|
|
$ cd binding/rust/ip2region
|
|
$ cargo test
|
|
$ cargo bench
|
|
|
|
// --snip---
|
|
ipv4_no_memory_bench time: [54.699 µs 57.401 µs 61.062 µs]
|
|
Found 16 outliers among 100 measurements (16.00%)
|
|
10 (10.00%) high mild
|
|
6 (6.00%) high severe
|
|
|
|
ipv4_vector_index_cache_bench
|
|
time: [25.972 µs 26.151 µs 26.360 µs]
|
|
Found 9 outliers among 100 measurements (9.00%)
|
|
1 (1.00%) low severe
|
|
6 (6.00%) high mild
|
|
2 (2.00%) high severe
|
|
|
|
ipv4_full_memory_cache_bench
|
|
time: [132.04 ns 139.48 ns 149.20 ns]
|
|
Found 10 outliers among 100 measurements (10.00%)
|
|
4 (4.00%) high mild
|
|
6 (6.00%) high severe
|
|
|
|
ipv6_no_memory_bench time: [121.00 µs 122.14 µs 123.40 µs]
|
|
Found 5 outliers among 100 measurements (5.00%)
|
|
2 (2.00%) high mild
|
|
3 (3.00%) high severe
|
|
|
|
ipv6_vector_index_cache_bench
|
|
time: [96.830 µs 100.23 µs 104.81 µs]
|
|
Found 8 outliers among 100 measurements (8.00%)
|
|
2 (2.00%) high mild
|
|
6 (6.00%) high severe
|
|
|
|
ipv6_full_memory_cache_bench
|
|
time: [175.29 ns 178.82 ns 183.77 ns]
|
|
Found 6 outliers among 100 measurements (6.00%)
|
|
2 (2.00%) high mild
|
|
4 (4.00%) high severe
|
|
// --snip--
|
|
```
|
|
|
|
## Testing, Result Verification, and Benchmark
|
|
|
|
```bash
|
|
$ cd binding/rust/example
|
|
$ cargo build -r
|
|
```
|
|
|
|
The location of the built executable is `binding/rust/target/release/searcher`
|
|
|
|
Testing IPv6 and IPv4 requires verifying query results against the contents of `ipv6_source.txt` and `ipv4_source.txt`.
|
|
|
|
**The query results shown here represent data at the current time; subsequent results may differ due to updates and corrections in the IP region segments of `ip_source.txt` and `xdb` binary data.**
|
|
|
|
#### Test IPv6
|
|
|
|
```bash
|
|
$ cd binding/rust
|
|
$ cargo build -r
|
|
$ ./target/release/searcher --xdb='../../data/ip2region_v6.xdb' query
|
|
ip2region xdb searcher test program, type `quit` or `Ctrl + c` to exit
|
|
ip2region>> ::
|
|
region: Ok(""), took: 79.651412ms
|
|
ip2region>> 240e:3b7:3273:51d0:cd38:8ae1:e3c0:b708
|
|
region: Ok("中国|广东省|深圳市|电信|CN"), took: 7.575µs
|
|
ip2region>> 2001::
|
|
region: Ok("0|0|Reserved|Reserved|Reserved"), took: 7.256µs
|
|
ip2region>> 2001:268:9a02:8888::
|
|
region: Ok("Japan|Aichi|Nagoya|KDDI CORPORATION|JP"), took: 7.921µs
|
|
ip2region>> 2a02:26f7:b408:a6c2::
|
|
region: Ok("United States|Virginia|Emporia|Akamai Technologies, Inc.|US"), took: 8.461µs
|
|
ip2region>> 2c99::
|
|
region: Ok("0|0|Reserved|Reserved|Reserved"), took: 5.33µs
|
|
```
|
|
|
|
#### Test IPv4
|
|
|
|
```bash
|
|
$ cd binding/rust
|
|
$ cargo build -r
|
|
$ ./target/release/searcher --xdb='../../data/ip2region_v4.xdb' query
|
|
ip2region xdb searcher test program, type `quit` or `Ctrl + c` to exit
|
|
ip2region>> 1.2.3.4
|
|
region: Ok("Australia|Queensland|Brisbane|0|AU"), took: 6.07µs
|
|
ip2region>> 1.1.2.1
|
|
region: Ok("中国|福建省|福州市|0|CN"), took: 5.653µs
|
|
ip2region>> 2.2.21.1
|
|
region: Ok("United States|Texas|0|Oracle Svenska AB|US"), took: 4.556µs
|
|
```
|
|
|
|
#### Benchmark and Result Verification
|
|
|
|
Test performance via the `searcher` program while comparing query results against `ip sources` files to check for errors.
|
|
|
|
```bash
|
|
$ cd binding/rust/example
|
|
$ cargo build -r
|
|
## Perform IPv4 bench test using data/ip2region_v4.xdb and data/ipv4_source.txt:
|
|
$ RUST_LOG=debug ../target/release/searcher --xdb='../../../data/ip2region_v4.xdb' bench '../../../data/ipv4_source.txt'
|
|
2025-09-24T07:02:07.840535Z DEBUG ip2region::searcher: Load xdb file with header header=Header { version: 3, index_policy: VectorIndex, create_time: 1757125456, start_index_ptr: 955933, end_index_ptr: 11042415, ip_version: V4, runtime_ptr_bytes: 4 }
|
|
2025-09-24T07:02:07.840894Z DEBUG ip2region::searcher: Load vector index cache
|
|
2025-09-24T07:02:07.840905Z DEBUG ip2region::searcher: Load full cache filepath="../../../data/ip2region_v4.xdb"
|
|
2025-09-24T07:02:08.409990Z INFO searcher: Benchmark finished count=3404406 took=569.388667ms avg_took=167ns
|
|
|
|
## Perform IPv6 bench test using data/ip2region_v6.xdb and data/ipv6_source.txt:
|
|
$ RUST_LOG=debug ../target/release/searcher --xdb='../../../data/ip2region_v6.xdb' bench '../../../data/ipv6_source.txt'
|
|
2025-09-24T07:01:48.991835Z DEBUG ip2region::searcher: Load xdb file with header header=Header { version: 3, index_policy: VectorIndex, create_time: 1756970508, start_index_ptr: 6585371, end_index_ptr: 647078145, ip_version: V6, runtime_ptr_bytes: 4 }
|
|
2025-09-24T07:01:48.992557Z DEBUG ip2region::searcher: Load vector index cache
|
|
2025-09-24T07:01:48.992563Z DEBUG ip2region::searcher: Load full cache filepath="../../../data/ip2region_v6.xdb"
|
|
2025-09-24T07:01:59.775879Z INFO searcher: Benchmark finished count=38335905 took=10.784124584s avg_took=281ns
|
|
```
|