fix(simulation): resolve clippy warnings in atlas modules

Replace HashMap/HashSet with BTreeMap/BTreeSet per D-030 determinism
rule. Fix while_let_loop, map_or simplification, collapsible if,
unsigned_abs casting, iterator indexing, and redundant wildcard arms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-02 22:52:15 +02:00
co-authored by Claude Opus 4.6
parent 718fcd0510
commit 6582ee4cca
6 changed files with 33 additions and 40 deletions
+7 -7
View File
@@ -69,7 +69,7 @@ fn role_row(economic_role: &str) -> usize {
"transit_hub" => 6,
"research" => 7,
"military" => 8,
"residential" | _ => 9,
_ => 9,
}
}
@@ -132,8 +132,8 @@ fn hungarian(cost: &[Vec<f32>]) -> Vec<usize> {
c[i][j] = cost[i][j];
}
// Pad extra columns with high cost so overflow cities pick them last.
for j in m..sz {
c[i][j] = f32::MAX / 2.0;
for item in c[i].iter_mut().take(sz).skip(m) {
*item = f32::MAX / 2.0;
}
}
// Pad extra rows with 0 cost (dummy workers).
@@ -228,8 +228,8 @@ fn synthetic_attractor(
let r = (dr * MIN_SPACING).min(grid_h as u16 - 1);
let c = (dc * MIN_SPACING).min(grid_w as u16 - 1);
let ok = placed.iter().all(|p| {
let dr2 = (p.position.0 as i32 - r as i32).abs() as u16;
let dc2 = (p.position.1 as i32 - c as i32).abs() as u16;
let dr2 = (p.position.0 as i32 - r as i32).unsigned_abs() as u16;
let dc2 = (p.position.1 as i32 - c as i32).unsigned_abs() as u16;
dr2.max(dc2) >= MIN_SPACING
});
if ok {
@@ -379,7 +379,7 @@ pub fn match_cities(
// -------------------------------------------------------------------------
// Phase 4: Synthetic overflow — all remaining cities
// -------------------------------------------------------------------------
let placed_ids: std::collections::HashSet<u64> =
let placed_ids: std::collections::BTreeSet<u64> =
placements.iter().map(|p| p.city_id).collect();
for city in cities {
@@ -401,7 +401,7 @@ pub fn match_cities(
// -------------------------------------------------------------------------
// Phase 5: Name fulfillment check
// -------------------------------------------------------------------------
let placed_ids: std::collections::HashSet<u64> =
let placed_ids: std::collections::BTreeSet<u64> =
placements.iter().map(|p| p.city_id).collect();
for city in cities {
if !placed_ids.contains(&city.city_id) {
+5 -5
View File
@@ -8,7 +8,7 @@
//! evicted on overflow, unless it is pinned (current player location or an
//! adjacent-system neighbor).
use std::collections::HashMap;
use std::collections::{BTreeMap, BTreeSet};
use bevy_ecs::prelude::Resource;
@@ -87,17 +87,17 @@ pub struct BodyWorldState {
/// invariant that `entries.len() <= capacity`.
#[derive(Resource, Debug, Default)]
pub struct BodyWorldStateCache {
entries: HashMap<String, BodyWorldState>,
entries: BTreeMap<String, BodyWorldState>,
/// Body IDs that must not be evicted regardless of `last_accessed`.
pinned: std::collections::HashSet<String>,
pinned: BTreeSet<String>,
capacity: usize,
}
impl BodyWorldStateCache {
pub fn new(capacity: usize) -> Self {
Self {
entries: HashMap::with_capacity(capacity),
pinned: std::collections::HashSet::new(),
entries: BTreeMap::new(),
pinned: BTreeSet::new(),
capacity,
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ fn role_row(economic_role: &str) -> usize {
"transit_hub" => 6,
"research" => 7,
"military" => 8,
"residential" | _ => 9,
_ => 9,
}
}
+14 -18
View File
@@ -181,8 +181,8 @@ fn flow_accumulation(fdir: &[i8], w: usize, h: usize) -> Vec<i32> {
}
let mut queue = VecDeque::new();
for i in 0..n {
if in_degree[i] == 0 {
for (i, &deg) in in_degree.iter().enumerate().take(n) {
if deg == 0 {
queue.push_back(i);
}
}
@@ -314,11 +314,9 @@ fn label_basins(fdir: &[i8], accum: &[i32], w: usize, h: usize) -> Vec<i32> {
for &(dr, dc) in &D8 {
let nr = r as i32 + dr;
let nc = (c as i32 + dc).rem_euclid(w as i32) as usize;
if nr >= 0 && nr < h as i32 {
if accum[nr as usize * w + nc] > accum[i] {
is_max = false;
break;
}
if nr >= 0 && nr < h as i32 && accum[nr as usize * w + nc] > accum[i] {
is_max = false;
break;
}
}
if is_max {
@@ -392,7 +390,7 @@ fn merge_small_basins(
for _ in 0..200 {
// Count basin sizes.
let mut sizes: std::collections::HashMap<i32, usize> = std::collections::HashMap::new();
let mut sizes: std::collections::BTreeMap<i32, usize> = std::collections::BTreeMap::new();
for &l in &labels {
*sizes.entry(l).or_insert(0) += 1;
}
@@ -432,15 +430,13 @@ fn merge_small_basins(
// Renumber contiguously from 0.
let unique: Vec<i32> = {
let mut set: std::collections::HashSet<i32> = std::collections::HashSet::new();
let mut set: std::collections::BTreeSet<i32> = std::collections::BTreeSet::new();
for &l in &labels {
set.insert(l);
}
let mut v: Vec<i32> = set.into_iter().collect();
v.sort();
v
set.into_iter().collect()
};
let remap: std::collections::HashMap<i32, i32> = unique
let remap: std::collections::BTreeMap<i32, i32> = unique
.iter()
.enumerate()
.map(|(new, &old)| (old, new as i32))
@@ -455,13 +451,13 @@ fn merge_small_basins(
fn find_largest_neighbor(
labels: &[i32],
target_id: i32,
sizes: &std::collections::HashMap<i32, usize>,
sizes: &std::collections::BTreeMap<i32, usize>,
w: usize,
h: usize,
) -> Option<i32> {
let n = w * h;
let mut neighbor_sizes: std::collections::HashMap<i32, usize> =
std::collections::HashMap::new();
let mut neighbor_sizes: std::collections::BTreeMap<i32, usize> =
std::collections::BTreeMap::new();
for i in 0..n {
if labels[i] != target_id {
@@ -497,8 +493,8 @@ fn find_largest_neighbor(
fn build_basins(labels: &[i32], w: usize, h: usize) -> Vec<DrainageBasin> {
let n = w * h;
let mut basin_map: std::collections::HashMap<i32, Vec<usize>> =
std::collections::HashMap::new();
let mut basin_map: std::collections::BTreeMap<i32, Vec<usize>> =
std::collections::BTreeMap::new();
for (i, &l) in labels.iter().enumerate() {
basin_map.entry(l).or_default().push(i);
+5 -8
View File
@@ -109,7 +109,7 @@ pub struct GenerationQueue {
/// Rayon thread pool dedicated to generation work.
pool: rayon::ThreadPool,
/// Set of body_ids currently in-flight to avoid duplicate submissions.
in_flight: Arc<Mutex<std::collections::HashSet<String>>>,
in_flight: Arc<Mutex<std::collections::BTreeSet<String>>>,
}
impl std::fmt::Debug for GenerationQueue {
@@ -150,7 +150,7 @@ impl GenerationQueue {
completion_tx: tx,
completion_rx: rx,
pool,
in_flight: Arc::new(Mutex::new(std::collections::HashSet::new())),
in_flight: Arc::new(Mutex::new(std::collections::BTreeSet::new())),
}
}
@@ -169,7 +169,7 @@ impl GenerationQueue {
// Check pending list.
let pending = self.pending.lock().unwrap();
if pending.iter().any(|q| {
q.item.body_id().map_or(false, |id| id == body_id)
q.item.body_id() == Some(body_id)
}) {
return;
}
@@ -193,11 +193,8 @@ impl GenerationQueue {
/// available without blocking.
pub fn drain_completions(&self) -> Vec<GenCompletion> {
let mut out = Vec::new();
loop {
match self.completion_rx.try_recv() {
Ok(c) => out.push(c),
Err(_) => break,
}
while let Ok(c) = self.completion_rx.try_recv() {
out.push(c);
}
out
}
+1 -1
View File
@@ -43,7 +43,7 @@ impl BodyHeightmap {
/// Returns `true` if the cell at (row, col) is land (above sea level).
#[inline]
pub fn is_land(&self, row: u32, col: u32) -> bool {
self.get(row, col).map_or(false, |e| e >= self.sea_level)
self.get(row, col).is_some_and(|e| e >= self.sea_level)
}
}