Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/znippy-zoomies

osm-katana/Cargo.toml

[package]
name        = "osm-katana"
# 0.2.8: DRIFTED from the published 0.2.7 at the same version — all eleven crates here
# were, and a version survey could not see it (local == registry for every one).
# Gate B found it: published znippy-zoomies 0.1.23 has no `STree32::len()`.
#
# 0.2.9: BUMPED rather than drifted again. `tiles::ScanLedger` is new public API and
# `TileStats` gained a public field, so 0.2.8 here would no longer be the 0.2.8 the
# registry holds — the exact shape the note above records. A new surface gets a new
# version; that is the whole lesson of Gate B.
# 0.2.10: BUMPED, same reason 0.2.9 was. DELTA 1 adds public surface —
# `shared::class` (the one tag → rung map), `shared::schema::min_zoom_field`, a
# `min_zoom` column in `network_fields()` and a `min_zoom_ladder` field on the public
# `NetworkRecipe` — so 0.2.9 here would no longer be the 0.2.9 the registry holds.
# 0.2.11: BUMPED, same reason 0.2.10 was. New public surface — `shared::height` (the
# one OSM height → metres decision, `HeightSource`, `METRES_PER_LEVEL`),
# `side_outputs::buildings` (the `buildings` table, `BuildingOptions`/`BuildingStats`/
# `extract_buildings`) and an `osm-katana buildings` CLI verb. 0.2.10 here would no
# longer be the 0.2.10 the registry holds.
# 0.2.12: BUMPED, same reason 0.2.9/0.2.10/0.2.11 were, and this one is a BREAKING
# signature change rather than an addition. Row 34 gives `side_outputs::buildings` an
# optional `roof:shape` column, so the three functions that describe the table's columns
# take the switch: `building_fields(roof_shape)`, `buildings_recipe(rg, generalise,
# roof_shape)`, and `BuildingOptions` gains a `roof_shape` field (a struct literal
# without it no longer compiles). 0.2.11 here would no longer be the 0.2.11 the registry
# holds — the exact shape the note above records.
# 0.2.13: BUMPED for row 24's new public surface, and one BREAKING change inside it.
# `verify` gains `SelfxVerdict`, `SelfxScratch`, `SELFX_PACK_{PAIRS_PER_SEG,PAIR_FLOOR,
# MAX_SEGS}` and `ring_self_intersects_bounded`, and `tiles` gains `SelfxBooks`,
# `selfx_books()` and `reset_selfx_books()`. The breaking half:
# `ring_self_intersects_bounded` now returns `(SelfxVerdict, usize)` — the pair tests it
# charged — because the pack books that work and the timing guard that used to assert a
# wall clock now asserts that count instead. A caller taking the bare verdict no longer
# compiles. 0.2.12 here would no longer be the 0.2.12 the registry holds.
version     = "0.3.0"
publish     = true
edition     = "2024"
description = "Fast OSM (XML/PBF) → GeoParquet/PBF converter with parallel decompression"
license     = "MIT"
repository  = "https://git.gunnar.rs/nordisk/znippy-zoomies"
readme      = "README.md"
# Development notes, agent instructions and machine-local tooling stay in the
# repository; they are not part of the published crate.
exclude = [
    ".nornir/",
    "CLAUDE.md",
    "bench_history.json",
]

[lib]
name = "osm_katana"

[[bin]]
name = "osm-katana"
path = "src/bin/main.rs"

[[bin]]
name = "vtd_bench"
path = "src/bin/vtd_bench.rs"

[[bin]]
name = "planet_bench"
path = "src/bin/planet_bench.rs"

[features]
# `pmtiles` WAS DECLARED HERE AND GATED NOTHING — zero `cfg(feature = "pmtiles")`
# sites in the whole repo, measured 2026-08-22, and no dependency behind it. It read
# as "osm-katana can emit PMTiles"; it never could. Deleted rather than allowlisted,
# for the same reason as the root crate's `vann-mmap`: an excuse for a flag that
# compiles nothing is a line that makes the rot permanent. `.nornir/…-design.md` on
# PMTiles stays — that is a design note about a format, not a claim about a build.
# `search-index` is the counter-example and stays: it gates four real `cfg` sites.
search-index = []
# Opt-in: pulls a pure-Rust BitTorrent client (librqbit) + tokio to fetch the
# OSM planet fixture. Off by default so `cargo build`/`test`/`bench` and
# `cargo publish` stay lean and pull nothing extra.
planet-fixture = ["dep:librqbit", "dep:tokio"]
# Convenience "dev mode" alias: `cargo build --features dev` turns on the
# planet torrent fixture. Same lean default/published build either way.
dev = ["planet-fixture"]
# `testmatrix` — turn `functional_status(component, check, ok, detail)` self-
# reports (the osm-katana CLI verb markers) into real nornir test-
# matrix rows. Compiled OUT of the default build (no nornir dep by default);
# pulls nornir-testmatrix's own `testmatrix` mode so the emit is a row-append.
testmatrix = ["dep:nornir-testmatrix", "nornir-testmatrix/testmatrix"]

[build-dependencies]
protobuf-codegen = "3"

[dependencies]
znippy-zoomies = { path = "..", version = "0.1.26" }
gatling        = { path = "../gatling", version = "0.1.13", package = "rotaryengine" }
lgz            = { path = "../lgz", version = "0.3.13" }
lbzip2         = { path = "../lbzip2", version = "0.5.11" }
zstd-sys-rs    = { path = "../zstd-sys-rs", version = "1.5.20" }
arrow          = "59"
flatbuffers    = "25.12.19"
# `geospatial` turns on the native GEOMETRY/GEOGRAPHY logical types and the
# writer-side bounding-box accumulator that fills `ColumnChunkMetaData::geo_statistics`.
# It is NOT a default feature of the crate, so a build without this line writes a
# plain BYTE_ARRAY and no reader can learn the column is geometry from the schema.
parquet        = { version = "59", features = ["geospatial"] }
# The `WkbType` arrow extension type. Declaring it on the arrow field is what makes
# `ArrowWriter` emit `LogicalType::Geometry` — there is no other door.
parquet-geospatial = "59"
# `parquet`'s own in-memory `ChunkReader` type — so a tile FETCHED from an object
# store can be inspected without first spilling it to a file (`TileRecipe::of_tile_bytes`).
bytes          = "1"
anyhow         = "1"
serde          = { version = "1", features = ["derive"] }
serde_json     = "1"
clap           = { version = "4", features = ["derive"] }
indicatif      = "0.18"
protobuf       = "3"
flate2         = "1.1"
# `mallinfo2` / `malloc_trim` — the allocator's own books, which is the only way to
# tell "this process is holding it" from "this program is using it". See
# `phase_log::malloc_bytes`.
libc           = "0.2"
ahash          = "0.8"
memchr         = "2"
memmap2        = "0.9"
# default-features OFF: librqbit's default `default-tls` = reqwest/native-tls = openssl-sys,
# a C library the pinned toolchain image does not carry (korp-server-gpu died on it in the
# container, oden 2026-09-29). `rust-tls` keeps the fetch pure Rust, as the law asks.
librqbit = { version = "9", optional = true, default-features = false, features = ["rust-tls", "http-api-client"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"], optional = true }
# testmatrix feature only; path dep to sibling nornir repo, off by default.
nornir-testmatrix = { version = "0.2", default-features = false, optional = true }

[dev-dependencies]
tempfile = "3"

# Block-parallel bz2, before and after, on the same bytes. `harness = false`:
# the arms are minutes long on a planet, which is not what a sampling harness is
# for — it prints bench_history-shaped rows and gets its timing/occupancy from
# `phase_log`, the same channel `convert --log` writes.
[[bench]]
name = "bz2_block_parallel"
harness = false

# What a region clip costs per node, three ways (simplify / gatling / raster mask)
# over REAL sampled node coordinates. Minutes-long arms again — no sampling harness.
[[bench]]
name = "clip_containment"
harness = false

# The pass-2 blob plan on the streaming .pbf path: both arms are the shipped
# converter (the control is `OSM_KATANA_PASS2_PLAN=0`), and every row carries
# wall time, core occupancy AND peak RSS. Minutes-long arms over a GiB-scale
# corpus — no sampling harness. Gate exits 1; `OSM_KATANA_BENCH_SABOTAGE=1` is
# the gate's own red test.
[[bench]]
name = "pbf_pass2_plan"
harness = false

# Tiling a region: core occupancy AND peak RSS, in the same row. Minutes-long
# arms over a real country extract, and the memory arm needs a stable process —
# no sampling harness. Gate exits 1 on either axis; see the module header.
[[bench]]
name = "tile_pyramid_parallel"
harness = false