Fast radix tree for IP addresses and DNS names
Project description
RadixTarget
RadixTarget is a performant radix implementation designed for quick lookups of IP addresses/networks and DNS hostnames.
RadixTarget is:
- Written in Rust with Python bindings
- Capable of ~200,000 lookups per second regardless of database size
- 100% test coverage
- Available as both a Rust crate and Python package
- Used by:
Python
Installation
pip install radixtarget
Usage
from radixtarget import RadixTarget
rt = RadixTarget()
# IPv4
rt.add("192.168.1.0/24")
rt.get("192.168.1.10") # IPv4Network("192.168.1.0/24")
rt.get("192.168.2.10") # None
# IPv6
rt.add("dead::/64")
rt.get("dead::beef") # IPv6Network("dead::/64")
rt.get("dead:cafe::beef") # None
# DNS
rt.add("net")
rt.add("www.example.com")
rt.add("test.www.example.com")
rt.get("net") # "net"
rt.get("evilcorp.net") # "net"
rt.get("www.example.com") # "www.example.com"
rt.get("asdf.test.www.example.com") # "test.www.example.com"
rt.get("example.com") # None
# Custom data nodes
rt.add("evilcorp.co.uk", "custom_data")
rt.get("www.evilcorp.co.uk") # "custom_data"
Rust
Installation
cargo add radixtarget
Usage
use radixtarget::{RadixTarget, ScopeMode};
use std::collections::HashSet;
// Create a new RadixTarget
let mut rt = RadixTarget::new(&[], ScopeMode::Normal);
// IPv4 networks and addresses
rt.insert("192.168.1.0/24");
assert_eq!(rt.get("192.168.1.100"), Some("192.168.1.0/24".to_string()));
assert_eq!(rt.get("192.168.2.100"), None);
// IPv6 networks and addresses
rt.insert("dead::/64");
assert_eq!(rt.get("dead::beef"), Some("dead::/64".to_string()));
assert_eq!(rt.get("cafe::beef"), None);
// DNS hostnames
rt.insert("example.com");
rt.insert("api.test.www.example.com");
assert_eq!(rt.get("example.com"), Some("example.com".to_string()));
assert_eq!(rt.get("subdomain.api.test.www.example.com"),
Some("api.test.www.example.com".to_string()));
// Check if target contains a value
assert!(rt.contains("192.168.1.50"));
assert!(rt.contains("dead::1234"));
assert!(rt.contains("example.com"));
// Get all hosts
let hosts: HashSet<String> = rt.hosts();
println!("All hosts: {:?}", hosts);
// Delete targets
assert!(rt.delete("192.168.1.0/24"));
assert!(!rt.delete("192.168.1.0/24")); // false - already deleted
// Utility operations
println!("Number of hosts: {}", rt.len());
println!("Is empty: {}", rt.is_empty());
// Prune dead nodes (returns number of pruned nodes)
let pruned_count = rt.prune();
// Defragment overlapping networks (returns (cleaned, new) hosts)
let (cleaned_hosts, new_hosts) = rt.defrag();
Scope Modes
RadixTarget supports different scope modes for DNS matching:
use radixtarget::{RadixTarget, ScopeMode};
// Normal mode: standard radix tree behavior (default)
let mut rt_normal = RadixTarget::new(&[], ScopeMode::Normal);
rt_normal.insert("example.com");
assert_eq!(rt_normal.get("subdomain.example.com"), Some("example.com".to_string()));
// Strict mode: exact matching only
let mut rt_strict = RadixTarget::new(&[], ScopeMode::Strict);
rt_strict.insert("example.com");
assert_eq!(rt_strict.get("example.com"), Some("example.com".to_string()));
assert_eq!(rt_strict.get("subdomain.example.com"), None); // No subdomain matching
// ACL mode: Same behavior as normal, but keeps only the highest parent subnet for efficiency
let mut rt_acl = RadixTarget::new(&[], ScopeMode::Acl);
rt_acl.insert("192.168.1.0/24");
rt_acl.insert("192.168.1.0/28");
// Least specific match is returned instead of most specific
assert_eq!(rt_acl.get("192.168.1.1"), Some("192.168.1.0/24".to_string()));
Initialization with Hosts
use radixtarget::{RadixTarget, ScopeMode};
// Initialize with existing hosts
let hosts = vec!["192.168.1.0/24", "example.com", "dead::/64"];
let rt = RadixTarget::new(&hosts, ScopeMode::Normal);
assert!(rt.contains("192.168.1.100"));
assert!(rt.contains("subdomain.example.com"));
assert!(rt.contains("dead::beef"));
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
radixtarget-4.0.0rc1.tar.gz
(668.9 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file radixtarget-4.0.0rc1.tar.gz.
File metadata
- Download URL: radixtarget-4.0.0rc1.tar.gz
- Upload date:
- Size: 668.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36c8c47be7c4ecd096dc5af6a7d6bdf319cd5639d74c5abe062fa0190ade025f
|
|
| MD5 |
5749ae7e55cb1ba2aefe011b6b34d2c4
|
|
| BLAKE2b-256 |
be61ffbe28eecef0e002c795d33876ca53e6289a477ed07f2f31004e28d734db
|
File details
Details for the file radixtarget-4.0.0rc1-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: radixtarget-4.0.0rc1-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 465.5 kB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.9.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df79d6eeac171a55f8a8e6bda7a4ac17dd1bf84800bd862530e8a12b0854eb51
|
|
| MD5 |
6db1bb3cacdd6e4476a32a5547ed63d2
|
|
| BLAKE2b-256 |
fc4060b97d0bf1a97d467a2befdfe4f99594cbbba54d44bbd7ede51153b33b3d
|