chore(rust): drop easily-inlined deps (anyhow, bytes, byteorder, num_cpus)
- anyhow: unused
- bytes: only a reqwest return-type annotation
- byteorder: replaced with std's from_le_bytes + try_into
- num_cpus: replaced with std:🧵:available_parallelism (stable 1.59)
No behavior change; 133 tests + clippy green.
This commit is contained in:
parent
a5f76896d0
commit
98aab767d0
7 changed files with 35 additions and 46 deletions
20
rust/prop_grid_rs/Cargo.lock
generated
20
rust/prop_grid_rs/Cargo.lock
generated
|
|
@ -695,12 +695,6 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hermit-abi"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hex"
|
name = "hex"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
|
@ -1266,16 +1260,6 @@ dependencies = [
|
||||||
"libm",
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num_cpus"
|
|
||||||
version = "1.17.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.4"
|
version = "1.21.4"
|
||||||
|
|
@ -1449,14 +1433,10 @@ dependencies = [
|
||||||
name = "prop_grid_rs"
|
name = "prop_grid_rs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"axum",
|
"axum",
|
||||||
"byteorder",
|
|
||||||
"bytes",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"flate2",
|
"flate2",
|
||||||
"futures",
|
"futures",
|
||||||
"num_cpus",
|
|
||||||
"png",
|
"png",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"prometheus",
|
"prometheus",
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,6 @@ path = "src/bin/hrrr_point_worker.rs"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros", "json"] }
|
sqlx = { version = "0.8", features = ["runtime-tokio-rustls", "postgres", "uuid", "chrono", "macros", "json"] }
|
||||||
reqwest = { version = "0.13", features = ["rustls", "stream"], default-features = false }
|
reqwest = { version = "0.13", features = ["rustls", "stream"], default-features = false }
|
||||||
bytes = "1"
|
|
||||||
anyhow = "1"
|
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
||||||
|
|
@ -29,8 +27,6 @@ chrono = { version = "0.4", features = ["serde"] }
|
||||||
uuid = { version = "1", features = ["v4", "serde"] }
|
uuid = { version = "1", features = ["v4", "serde"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
num_cpus = "1"
|
|
||||||
byteorder = "1"
|
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
rayon = "1.12"
|
rayon = "1.12"
|
||||||
axum = { version = "0.8", default-features = false, features = ["http1", "tokio"] }
|
axum = { version = "0.8", default-features = false, features = ["http1", "tokio"] }
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let parallelism: usize = std::env::var("PROP_GRID_RS_PARALLELISM")
|
let parallelism: usize = std::env::var("PROP_GRID_RS_PARALLELISM")
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| v.parse().ok())
|
.and_then(|v| v.parse().ok())
|
||||||
.unwrap_or_else(num_cpus::get)
|
.unwrap_or_else(|| {
|
||||||
|
std::thread::available_parallelism()
|
||||||
|
.map(|n| n.get())
|
||||||
|
.unwrap_or(1)
|
||||||
|
})
|
||||||
.max(1);
|
.max(1);
|
||||||
// +2 slots over parallelism: each worker holds one connection during
|
// +2 slots over parallelism: each worker holds one connection during
|
||||||
// claim/complete transactions; the spare lets NOTIFY and an opportunistic
|
// claim/complete transactions; the spare lets NOTIFY and an opportunistic
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ use std::process::{Command, Output};
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicU64, Ordering};
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
|
|
||||||
use crate::grid::{round3, GridSpec};
|
use crate::grid::{round3, GridSpec};
|
||||||
|
|
||||||
const UNDEFINED_VALUE: f32 = 9.999e20;
|
const UNDEFINED_VALUE: f32 = 9.999e20;
|
||||||
|
|
@ -244,7 +242,9 @@ pub fn parse_lola_binary(bin: &[u8], messages: &[Message], grid_spec: &GridSpec)
|
||||||
let lat_key = (lat * 1000.0).round() as i32;
|
let lat_key = (lat * 1000.0).round() as i32;
|
||||||
for i in 0..nx {
|
for i in 0..nx {
|
||||||
let cell_offset = (j * nx + i) * 4;
|
let cell_offset = (j * nx + i) * 4;
|
||||||
let value = LittleEndian::read_f32(&chunk[cell_offset..cell_offset + 4]);
|
let value = f32::from_le_bytes(
|
||||||
|
chunk[cell_offset..cell_offset + 4].try_into().unwrap(),
|
||||||
|
);
|
||||||
if value > UNDEFINED_VALUE / 2.0 {
|
if value > UNDEFINED_VALUE / 2.0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
//! max dBZ in a ~25 km box, matching Elixir's
|
//! max dBZ in a ~25 km box, matching Elixir's
|
||||||
//! `extract_box/5` output field `max_reflectivity_dbz`.
|
//! `extract_box/5` output field `max_reflectivity_dbz`.
|
||||||
|
|
||||||
use bytes::Bytes;
|
|
||||||
use chrono::{DateTime, Datelike, Timelike, Utc};
|
use chrono::{DateTime, Datelike, Timelike, Utc};
|
||||||
|
|
||||||
pub const LON_MIN: f64 = -126.0;
|
pub const LON_MIN: f64 = -126.0;
|
||||||
|
|
@ -136,7 +135,7 @@ pub async fn fetch_frame(
|
||||||
if !resp.status().is_success() {
|
if !resp.status().is_success() {
|
||||||
return Err(NexradError::Status(resp.status().as_u16()));
|
return Err(NexradError::Status(resp.status().as_u16()));
|
||||||
}
|
}
|
||||||
let body: Bytes = resp.bytes().await?;
|
let body = resp.bytes().await?;
|
||||||
let (pixels, width) = decode_n0q_png(&body)?;
|
let (pixels, width) = decode_n0q_png(&body)?;
|
||||||
|
|
||||||
let obs = points
|
let obs = points
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,6 @@ fn clamp_score(s: i32) -> u8 {
|
||||||
/// the raw row-major body plus the metadata. Mirrors the Elixir
|
/// the raw row-major body plus the metadata. Mirrors the Elixir
|
||||||
/// `decode/1` sans Access-behavior niceties.
|
/// `decode/1` sans Access-behavior niceties.
|
||||||
pub fn decode(bytes: &[u8]) -> Option<Decoded> {
|
pub fn decode(bytes: &[u8]) -> Option<Decoded> {
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
if bytes.len() < 4 + 1 + 4 + 8 + 4 + 4 + 4 + 2 + 2 {
|
if bytes.len() < 4 + 1 + 4 + 8 + 4 + 4 + 4 + 2 + 2 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -183,13 +182,13 @@ pub fn decode(bytes: &[u8]) -> Option<Decoded> {
|
||||||
if bytes[4] != VERSION {
|
if bytes[4] != VERSION {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let band_mhz = LittleEndian::read_u32(&bytes[5..9]);
|
let band_mhz = u32::from_le_bytes(bytes[5..9].try_into().ok()?);
|
||||||
let valid_time_unix = LittleEndian::read_i64(&bytes[9..17]);
|
let valid_time_unix = i64::from_le_bytes(bytes[9..17].try_into().ok()?);
|
||||||
let lat_min = LittleEndian::read_f32(&bytes[17..21]);
|
let lat_min = f32::from_le_bytes(bytes[17..21].try_into().ok()?);
|
||||||
let lon_min = LittleEndian::read_f32(&bytes[21..25]);
|
let lon_min = f32::from_le_bytes(bytes[21..25].try_into().ok()?);
|
||||||
let step = LittleEndian::read_f32(&bytes[25..29]);
|
let step = f32::from_le_bytes(bytes[25..29].try_into().ok()?);
|
||||||
let n_rows = LittleEndian::read_u16(&bytes[29..31]);
|
let n_rows = u16::from_le_bytes(bytes[29..31].try_into().ok()?);
|
||||||
let n_cols = LittleEndian::read_u16(&bytes[31..33]);
|
let n_cols = u16::from_le_bytes(bytes[31..33].try_into().ok()?);
|
||||||
let body_len = (n_rows as usize) * (n_cols as usize);
|
let body_len = (n_rows as usize) * (n_cols as usize);
|
||||||
if bytes.len() < 33 + body_len {
|
if bytes.len() < 33 + body_len {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
use std::io::{Cursor, Read};
|
use std::io::{Cursor, Read};
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
|
||||||
use prop_grid_rs::{band_config, scorer};
|
use prop_grid_rs::{band_config, scorer};
|
||||||
|
|
||||||
fn opt(v: f64) -> Option<f64> {
|
fn opt(v: f64) -> Option<f64> {
|
||||||
|
|
@ -22,14 +21,26 @@ fn opt(v: f64) -> Option<f64> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_exact<const N: usize>(r: &mut Cursor<&[u8]>) -> [u8; N] {
|
||||||
|
let mut buf = [0u8; N];
|
||||||
|
r.read_exact(&mut buf).expect("read_exact");
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
fn read_f64(r: &mut Cursor<&[u8]>) -> f64 {
|
fn read_f64(r: &mut Cursor<&[u8]>) -> f64 {
|
||||||
r.read_f64::<LittleEndian>().expect("f64")
|
f64::from_le_bytes(read_exact::<8>(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(r: &mut Cursor<&[u8]>) -> u32 {
|
||||||
|
u32::from_le_bytes(read_exact::<4>(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_i32(r: &mut Cursor<&[u8]>) -> i32 {
|
||||||
|
i32::from_le_bytes(read_exact::<4>(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u8(r: &mut Cursor<&[u8]>) -> u8 {
|
fn read_u8(r: &mut Cursor<&[u8]>) -> u8 {
|
||||||
let mut buf = [0u8; 1];
|
read_exact::<1>(r)[0]
|
||||||
r.read_exact(&mut buf).expect("u8");
|
|
||||||
buf[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -38,7 +49,7 @@ fn matches_elixir_golden_fixture() {
|
||||||
.expect("tests/scores.bincode — run `mix rust.golden` first");
|
.expect("tests/scores.bincode — run `mix rust.golden` first");
|
||||||
let mut r = Cursor::new(bytes.as_slice());
|
let mut r = Cursor::new(bytes.as_slice());
|
||||||
|
|
||||||
let n = r.read_u32::<LittleEndian>().expect("n_samples");
|
let n = read_u32(&mut r);
|
||||||
assert!(n > 0, "empty fixture");
|
assert!(n > 0, "empty fixture");
|
||||||
|
|
||||||
let mut mismatches: Vec<String> = Vec::new();
|
let mut mismatches: Vec<String> = Vec::new();
|
||||||
|
|
@ -63,8 +74,8 @@ fn matches_elixir_golden_fixture() {
|
||||||
best_duct_band_ghz: opt(read_f64(&mut r)),
|
best_duct_band_ghz: opt(read_f64(&mut r)),
|
||||||
bulk_richardson: opt(read_f64(&mut r)),
|
bulk_richardson: opt(read_f64(&mut r)),
|
||||||
};
|
};
|
||||||
let band_mhz = r.read_u32::<LittleEndian>().expect("band_mhz");
|
let band_mhz = read_u32(&mut r);
|
||||||
let expected = r.read_i32::<LittleEndian>().expect("expected_score");
|
let expected = read_i32(&mut r);
|
||||||
|
|
||||||
let band = band_config::get(band_mhz).expect("band in config");
|
let band = band_config::get(band_mhz).expect("band in config");
|
||||||
let got = scorer::composite_score(&c, band).score;
|
let got = scorer::composite_score(&c, band).score;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue