netindex
Read and write immutable IP-range and exact-ASN indexes. Each assertion retains its original target and an opaque payload. Queries return every match, including overlaps and duplicates.
Licensed under either MIT or Apache-2.0, at your option.
Quick start
Add netindex to your dependencies:
[]
= "0.1"
use ;
let mut builder = new;
builder.push?;
let bytes = builder.into_bytes?;
let reader = open?;
let matches = reader.lookup_ip?;
assert_eq!;
for matched in matches
# Ok::
API overview
| Type | Purpose |
|---|---|
[Builder] |
Buffer unsorted assertions and encode to bytes or a writer. |
[Reader] |
Validate backing bytes and query the index. |
[Target] |
An IP address, canonical CIDR, inclusive range, or nonzero ASN. |
[Match] |
Original target, insertion-order ID, and borrowed payload. |
[Limits] |
Record and complete-file byte ceilings. |
[CoverageRouter] |
Select possible readers when querying multiple files. |
ExternalBuilder |
Build with bounded buffers and temporary files; requires external-sort. |
Reading
[Reader::open] accepts immutable AsRef<[u8]> backing: owned bytes, a borrowed
slice, or a caller-owned mapping. Opening validates the complete index. Payload
decoding belongs to the application.
[Reader::lookup_ip] and [Reader::lookup_asn] collect borrowed matches into a
vector. Misses return an empty vector. Exact-ASN lookup does not resolve an IP's
ASN. Payloads remain valid while their reader is retained.
Use [Reader::visit_ip], [Reader::visit_asn], or [Reader::visit_all] to process
matches without allocating a result vector. A visitor error stops delivery and
retains the application's error type:
# use ;
# let mut builder = new;
# builder.push?;
# let reader = open?;
reader.visit_ip?;
# Ok::
For up to 64 files, derive each reader's coverage and pass it to
[CoverageRouter::new] in reader order. Query every returned candidate. Coverage
can admit misses but does not discard matches. Retain readers and their router
together; rebuild the router when the reader set changes. ASN queries still visit
each reader's exact-ASN index.
Building
[Builder] accepts unsorted assertions. [Builder::into_bytes] returns owned
encoded bytes; [Builder::write_to] writes the same format into a caller-owned
writer. Identical payloads share bytes without merging assertions. Metadata is
stored once and remains opaque.
Enable external-sort for ExternalBuilder when buffering all assertions would
exceed the desired working set. It sorts bounded runs on disk and preserves
insertion-order IDs. ExternalOptions controls run size, payload-cache bytes, and
temporary-disk usage. An uncached repeated payload may occupy additional output
bytes. Failed pushes invalidate this builder; discard it.
External finalization requires an empty seekable output at position zero. Both writers can leave partial output on failure. Stage output and publish it only after successful finalization and any application payload checks. Synchronization and release activation belong to the caller.
MMDB conversion
Enable mmdb for mmdb::visit_networks. It validates a native MMDB reader, then
visits one network at a time. The callback encodes application fields and pushes
into Builder or ExternalBuilder; it can skip records without adding assertions.
Input may be owned bytes or a mapping. It cannot be parsed directly from a
sequential download stream.
Iteration options control aliases, empty records, and networks without data. Include aliased networks when preserving native IPv6 alias lookups. Conversion errors stop delivery but do not undo earlier pushes; discard the partial build. Payload schemas, metadata selection, and output publication remain caller-owned.
Memory and files
Default limits are one million assertions and 128 MiB per file. These bound logical records and bytes, not process RSS. Validation state, allocator overhead, caller buffers, and the OS file cache consume additional memory.
The crate does not open or map files. A mapping owner must keep its file unchanged for the reader's lifetime. Mapped-page faults can block a lookup even though index search performs no explicit I/O. Choose owned bytes or a mapping for the workload.
Threads and runtimes
Reader<B> is Send + Sync when its backing is. Share it through Arc or borrow
it across scoped threads; sharing does not copy database bytes. Each caller owns
its visitor and result storage. The crate creates no threads and uses no runtime.
Parallelize independent queries or bounded batches. Move opening, building, and substantial lookup work away from async runtime workers. Bound admitted jobs and keep permits inside blocking jobs until they finish, including after cancellation.
The Tokio and compio examples share readers with bounded blocking workers and await admitted work before returning a batch failure:
Features
| Feature | Behavior |
|---|---|
external-sort |
Disk-backed building with configurable buffer and temporary-file limits. |
mmdb |
Validated network iteration for caller-defined MMDB conversion. |
simd |
Runtime AVX2 dispatch on x86-64, with scalar fallback. File bytes are unchanged. |
All features are disabled by default. Global target-cpu=native is not required.
The supported toolchain is Rust 1.95. The public error enum is non-exhaustive;
error messages are diagnostics, not a stable wire format.
The file specification defines the encoded layout and validation rules.
See contributor documentation for checks and benchmarks.