binding/rust/README.md
:globe_with_meridians: 中文简体 | English
ip2region rust Query Clientip strings and u32/u28 numeric types| 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 |
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.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.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.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.Create a new project using cargo, such as cargo new ip-test
Configure [dependencies] in Cargo.toml as follows:
[dependencies]
ip2region = { git = "https://github.com/lionsoul2014/ip2region.git", branch = "master" }
Write main.rs
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}");
}
}
}
$ 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--
$ 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.
$ 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
$ 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
Test performance via the searcher program while comparing query results against ip sources files to check for errors.
$ 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