From 500f74b7008915cb073bfd86c3c100d8fb5ab2cd Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Fri, 6 Nov 2026 22:30:03 -0800 Subject: [PATCH] Tests: the index read count includes entries read from more than one cell RectIndex::at notes its reads before it sorts and removes repeats, so an entry filed under several of the cells a lookup spans counts once per cell. --- crates/pathops/src/planar/index.rs | 4 ++-- crates/pathops/src/planar/tests.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/pathops/src/planar/index.rs b/crates/pathops/src/planar/index.rs index 7d709e80d..3c7d9f9be 100644 --- a/crates/pathops/src/planar/index.rs +++ b/crates/pathops/src/planar/index.rs @@ -219,10 +219,10 @@ impl RectIndex { } } } - found.sort_unstable(); - found.dedup(); #[cfg(test)] note_work(found.len()); + found.sort_unstable(); + found.dedup(); found.into_iter().filter_map(move |i| self.items.get(i)).filter(move |(r, _)| r.inflate(tol, tol).contains(p)).map(|(_, t)| t) } } diff --git a/crates/pathops/src/planar/tests.rs b/crates/pathops/src/planar/tests.rs index 025d760f4..f9b88a27f 100644 --- a/crates/pathops/src/planar/tests.rs +++ b/crates/pathops/src/planar/tests.rs @@ -738,6 +738,19 @@ fn rect_index_reads_a_diagonal_hatch_only_near_the_point() { assert_eq!(index.at(Point::new(-5.0, 0.0), 0.1).count(), 0); } +#[test] +fn rect_index_counts_each_entry_it_reads() { + // Ten collinear lines filed under each of the 10 cells along them: a lookup 300 pt either side + // reads every line from each of the cells it spans, more than once per line. + let line = PathSeg::Line(kurbo::Line::new((0.0, 0.0), (1000.0, 0.0))); + let items: Vec<_> = (0..10).map(|k| (line.bounding_box(), (line, k))).collect(); + let index = RectIndex::with_footprint(items, |r, (s, _), cell| segment_footprint(r, s, cell)); + let started = work_done(); + assert_eq!(index.at(Point::new(500.0, 0.0), 300.0).count(), 10); + let work = work_done() - started; + assert!(work >= 50, "{work} reads"); +} + /// The grid's memory stays linear in the item count: pieces of one segment falling in the same /// cell file it once, and coincident segments (each along every cell of a one-column grid) go /// to the scanned list once the grid holds its budget of references, and are still all found.