From 1d5d3de85c5f74a4c69e753872367587e4e113a4 Mon Sep 17 00:00:00 2001 From: laizy <4203231+laizy@users.noreply.github.com> Date: Fri, 30 May 2025 23:23:27 +0800 Subject: [PATCH] gpui: Optimize the ordering update in the BoundsTree (#31025) Release Notes: - N/A --- crates/gpui/src/bounds_tree.rs | 44 ++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/gpui/src/bounds_tree.rs b/crates/gpui/src/bounds_tree.rs index 44840ac1d3902db4de7b3f7f5d59dd5c9a015836..03f83b95035489bd86201c4d64c15f5a12ed50ea 100644 --- a/crates/gpui/src/bounds_tree.rs +++ b/crates/gpui/src/bounds_tree.rs @@ -111,7 +111,7 @@ where self.root = Some(new_parent); } - for node_index in self.stack.drain(..) { + for node_index in self.stack.drain(..).rev() { let Node::Internal { max_order: max_ordering, .. @@ -119,7 +119,10 @@ where else { unreachable!() }; - *max_ordering = cmp::max(*max_ordering, ordering); + if *max_ordering >= ordering { + break; + } + *max_ordering = ordering; } ordering @@ -237,6 +240,7 @@ where mod tests { use super::*; use crate::{Bounds, Point, Size}; + use rand::{Rng, SeedableRng}; #[test] fn test_insert() { @@ -294,4 +298,40 @@ mod tests { assert_eq!(tree.insert(bounds5), 1); // bounds5 does not overlap with any other bounds assert_eq!(tree.insert(bounds6), 2); // bounds6 overlaps with bounds4, so it should have a different order } + + #[test] + fn test_random_iterations() { + let max_bounds = 100; + for seed in 1..=1000 { + // let seed = 44; + let mut tree = BoundsTree::default(); + let mut rng = rand::rngs::StdRng::seed_from_u64(seed as u64); + let mut expected_quads: Vec<(Bounds, u32)> = Vec::new(); + + // Insert a random number of random AABBs into the tree. + let num_bounds = rng.gen_range(1..=max_bounds); + for _ in 0..num_bounds { + let min_x: f32 = rng.gen_range(-100.0..100.0); + let min_y: f32 = rng.gen_range(-100.0..100.0); + let width: f32 = rng.gen_range(0.0..50.0); + let height: f32 = rng.gen_range(0.0..50.0); + let bounds = Bounds { + origin: Point { x: min_x, y: min_y }, + size: Size { width, height }, + }; + + let expected_ordering = expected_quads + .iter() + .filter_map(|quad| quad.0.intersects(&bounds).then_some(quad.1)) + .max() + .unwrap_or(0) + + 1; + expected_quads.push((bounds, expected_ordering)); + + // Insert the AABB into the tree and collect intersections. + let actual_ordering = tree.insert(bounds); + assert_eq!(actual_ordering, expected_ordering); + } + } + } }