xdb-parse 0.1.0

A parser to xdb files like ip2region
Documentation
# xdb-parse

A parser to xdb files like ip2region
A high-performance Rust library for parsing and querying IP database files (xdb format) like ip2region. Supports both IPv4 and IPv6 address lookup with efficient binary search algorithms.

## Features


- **Dual Protocol Support**: Full support for both IPv4 and IPv6 address lookup
- **High Performance**: Optimized binary search algorithm for fast IP queries
- **Memory Efficient**: Load database files once and query multiple times
- **Thread Safe**: Designed for concurrent usage in multi-threaded environments
- **Flexible Input**: Accepts IP addresses in multiple formats (string, numeric)
- **Zero Dependencies**: Minimal external dependencies for reliability

## Installation


Add this to your `Cargo.toml`:

```toml
[dependencies]
xdb-parse = "0.1.0"
```

## Quick Start


### Basic Usage


```rust
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;

fn main() -> Result<()> {
    // Load the IP database file
    let path = "./assets/ip2region_v4.xdb";
    let data = load_file(path.into())?;
    
    // Search for an IP address
    let result = search_ip("73.24.63.66", &data)?;
    println!("IP location: {}", result);
    
    Ok(())
}
```

### IPv6 Support


```rust
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;

fn main() -> Result<()> {
    // Load IPv6 database
    let path = "./assets/ip2region_v6.xdb";
    let data = load_file(path.into())?;
    
    // Search for IPv6 address
    let result = search_ip("2001:0db8:85a3:0000:0000:8a2e:0370:7334", &data)?;
    println!("IPv6 location: {}", result);
    
    Ok(())
}
```

## Examples


### Example 1: Basic IP Lookup


See `examples/search_ip.rs`:

```rust
use std::time::Instant;
use anyhow::Result;
use xdb_parse::utils::{load_file, search_ip};

fn main() -> Result<()> {
    let start = Instant::now();
    let path = "./assets/ip2region_v4.xdb";
    let data = load_file(path.into())?;
    
    let ret = search_ip("73.24.63.66", &data)?;
    let time = start.elapsed();
    
    println!("Search time: {:?} - Result: {}", time, ret);
    Ok(())
}
```

### Example 2: Multi-threaded Usage


The library is designed for thread-safe concurrent usage:

```rust
use std::{sync::Arc, thread};
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;

fn main() -> Result<()> {
    let path = "./assets/ip2region_v6.xdb";
    let data = Arc::new(load_file(path.into())?);
    
    let data_clone = Arc::clone(&data);
    let handle = thread::spawn(move || {
        let result = search_ip("2408:8352:da10:1ad:c283:c9ff:fec6:4046", &data_clone).unwrap();
        println!("Thread result: {}", result);
    });
    
    // Main thread can also query
    let result = search_ip("2408:8352:da10:1ad:c283:c9ff:fec6:4046", &data)?;
    println!("Main thread result: {}", result);
    
    handle.join().unwrap();
    Ok(())
}
```

### Example 3: Performance Benchmarking


See `benches/search.rs` for performance testing:

```rust
use criterion::{Criterion, criterion_group, criterion_main};
use xdb_parse::utils::{load_file, search_ip};

fn search_benchmark(c: &mut Criterion) {
    c.bench_function("ipv4_search", |b| {
        let path = "./assets/ip2region_v4.xdb";
        let data = load_file(path.into()).unwrap();
        b.iter(|| {
            search_ip("73.24.63.66", &data).unwrap();
        })
    });
}

criterion_group!(benches, search_benchmark);
criterion_main!(benches);
```

## API Reference


### Core Functions


#### `load_file(path: PathBuf) -> Result<Vec<u8>, XdbError>`


Loads an xdb database file into memory.

**Parameters:**
- `path`: Path to the xdb file

**Returns:** Byte vector containing the database data

#### `search_ip(ip: &str, data: &[u8]) -> Result<String, XdbError>`


Searches for an IP address in the loaded database.

**Parameters:**
- `ip`: IP address to search (supports multiple formats)
- `data`: Database data loaded by `load_file`

**Returns:** Location information as string

### Supported IP Formats


The library accepts IP addresses in multiple formats:

```rust
// Standard IPv4 format
search_ip("192.168.1.1", &data)?;

// Standard IPv6 format  
search_ip("2001:0db8:85a3::0370:7334", &data)?;

// Numeric format (IPv4)
search_ip("3232235777", &data)?; // Equivalent to 192.168.1.1

// Numeric format (IPv6)
search_ip("42540766411282592856903984951653826560", &data)?;
```

## Database File Format


The library supports the xdb format used by ip2region:

- **Header**: 256 bytes containing metadata
- **Vector Index**: 256×256 index blocks for fast lookup
- **Segment Data**: IP range segments with location information

### File Structure


```
┌─────────────────┐
│     Header      │ 256 bytes
├─────────────────┤
│   Vector Index  │ 256×256×8 bytes
├─────────────────┤
│  Segment Data   │ Variable length
└─────────────────┘
```

## Performance


The library uses an optimized binary search algorithm:

- **IPv4 Lookup**: ~5 microseconds per query
- **IPv6 Lookup**: ~250 microseconds per query
- **Memory Usage**: Database loaded once, shared across threads

## Error Handling


The library uses `thiserror` for comprehensive error handling:

```rust
use xdb_parse::error::XdbError;

match search_ip("invalid_ip", &data) {
    Ok(result) => println!("Location: {}", result),
    Err(XdbError::InvalidIP(msg)) => println!("Invalid IP: {}", msg),
    Err(e) => println!("Error: {}", e),
}
```

## Running Examples


To run the provided examples:

```bash
# Run the basic search example

cargo run --example search_ip

# Run benchmarks

cargo bench

# Run tests

cargo test
```

## License


This project is licensed under the same terms as Rust itself.

## Contributing


Contributions are welcome! Please feel free to submit issues and pull requests.

## Acknowledgments


- Inspired by the ip2region project
- Uses efficient binary search algorithms for fast IP lookup
- Designed for high-performance applications