use rustsim_spaces::continuous3d::ContinuousPos3D;
use rustsim_spaces::hybrid::{HybridPos, HybridSpace, ZoneExtent};
use std::time::Instant;
#[test]
fn hybrid_space_neighbor_query_soak_with_spatial_hash() {
const ZONES: usize = 8;
const AGENTS_PER_ZONE: usize = 1_000;
const QUERY_REPEATS: usize = 200;
let extent = ZoneExtent::cube(100.0).unwrap();
let mut space = HybridSpace::uniform(ZONES, extent);
for zone in 0..(ZONES - 1) {
assert!(space.add_edge(zone, zone + 1));
}
for zone in 0..ZONES {
space.enable_zone_spatial_hash(zone, 5.0).unwrap();
}
let mut next_id = 1u64;
for zone in 0..ZONES {
for i in 0..AGENTS_PER_ZONE {
let x = (i % 50) as f64 * 1.5 + 1.0;
let y = ((i / 50) % 20) as f64 * 2.0 + 1.0;
let z = (i % 10) as f64 * 0.5 + 1.0;
space
.add_agent_internal(next_id, HybridPos::new(zone, ContinuousPos3D::new(x, y, z)))
.unwrap();
next_id += 1;
}
}
let query = HybridPos::new(3, ContinuousPos3D::new(20.0, 20.0, 2.0));
let t0 = Instant::now();
let mut total_hits = 0usize;
for _ in 0..QUERY_REPEATS {
total_hits += space.nearby_ids_same_zone(&query, 8.0).len();
total_hits += space.nearby_ids_by_hops(query.node, 2).len();
total_hits += space.nearby_ids(&query, 1, 8.0).len();
}
let elapsed_ms = t0.elapsed().as_millis();
assert!(total_hits > 0);
assert!(space.has_zone_spatial_hash(3));
assert_eq!(space.agents_at_node(3).len(), AGENTS_PER_ZONE);
eprintln!(
"[hybrid soak] {} zones x {} agents, {} query rounds in {} ms",
ZONES, AGENTS_PER_ZONE, QUERY_REPEATS, elapsed_ms
);
}
#[test]
#[ignore]
fn hybrid_space_scale_profile_large_population() {
const ZONES: usize = 16;
const AGENTS_PER_ZONE: usize = 2_500;
let extent = ZoneExtent::cube(150.0).unwrap();
let mut space = HybridSpace::uniform(ZONES, extent);
for zone in 0..(ZONES - 1) {
assert!(space.add_edge(zone, zone + 1));
}
for zone in 0..ZONES {
space.enable_zone_spatial_hash(zone, 6.0).unwrap();
}
let mut next_id = 1u64;
for zone in 0..ZONES {
for i in 0..AGENTS_PER_ZONE {
let x = (i % 100) as f64 * 1.2 + 1.0;
let y = ((i / 100) % 25) as f64 * 1.5 + 1.0;
let z = (i % 8) as f64 * 0.75 + 1.0;
space
.add_agent_internal(next_id, HybridPos::new(zone, ContinuousPos3D::new(x, y, z)))
.unwrap();
next_id += 1;
}
}
let query = HybridPos::new(5, ContinuousPos3D::new(30.0, 30.0, 3.0));
let t0 = Instant::now();
let same_zone = space.nearby_ids_same_zone(&query, 10.0);
let hops = space.nearby_ids_by_hops(query.node, 3);
let mixed = space.nearby_ids(&query, 2, 10.0);
let elapsed_ms = t0.elapsed().as_millis();
assert!(!same_zone.is_empty());
assert!(hops.len() >= AGENTS_PER_ZONE);
assert!(mixed.len() >= same_zone.len());
eprintln!(
"[hybrid scale] {} total agents queried in {} ms",
ZONES * AGENTS_PER_ZONE,
elapsed_ms
);
}