From c45eb0a12bd9dfdbc257ed238b2ee86d8565d42f Mon Sep 17 00:00:00 2001 From: Nail Sharipov Date: Fri, 27 Mar 2026 11:15:56 +0300 Subject: [PATCH 1/3] remove direct item access operation --- iOverlay/src/split/solver_list.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iOverlay/src/split/solver_list.rs b/iOverlay/src/split/solver_list.rs index c048b17..039bfad 100644 --- a/iOverlay/src/split/solver_list.rs +++ b/iOverlay/src/split/solver_list.rs @@ -24,20 +24,20 @@ impl SplitSolver { let radius: i64 = snap_radius.radius(); - for i in 0..segments.len() - 1 { - let ei = &segments[i].x_segment; - let ri = ei.y_range(); - for (j, s) in segments.iter().enumerate().skip(i + 1) { - let ej = &s.x_segment; - if ei.b.x < ej.a.x { + for (i, si) in segments.iter().enumerate() { + let xsi = &si.x_segment; + let ri = xsi.y_range(); + for (j, sj) in segments.iter().enumerate().skip(i + 1) { + let xsj = &sj.x_segment; + if xsi.b.x < xsj.a.x { break; } - if ej.is_not_intersect_y_range(&ri) { + if xsj.is_not_intersect_y_range(&ri) { continue; } - let is_round = SplitSolver::cross(i, j, ei, ej, &mut self.marks, radius); + let is_round = SplitSolver::cross(i, j, xsi, xsj, &mut self.marks, radius); need_to_fix = need_to_fix || is_round } } From 036d21eac13f4bb73b10f1c64ca5b65314ff4675 Mon Sep 17 00:00:00 2001 From: Nail Sharipov Date: Sat, 28 Mar 2026 09:44:57 +0300 Subject: [PATCH 2/3] add min supported rust version --- .github/workflows/tests.yml | 11 +++++++++++ iOverlay/Cargo.toml | 1 + 2 files changed, 12 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index da083e8..5c83e8b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,6 +8,17 @@ on: branches: ["main"] jobs: + msrv: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: 1.88.0 + - name: Run MSRV check + working-directory: iOverlay + run: cargo check --all-features --all-targets + test: runs-on: ubuntu-latest steps: diff --git a/iOverlay/Cargo.toml b/iOverlay/Cargo.toml index 4614400..e084de1 100644 --- a/iOverlay/Cargo.toml +++ b/iOverlay/Cargo.toml @@ -3,6 +3,7 @@ name = "i_overlay" version = "4.5.1" authors = ["Nail Sharipov "] edition = "2024" +rust-version = "1.88" description = "Boolean Operations for 2D Polygons: Supports intersection, union, difference, xor, and self-intersections for all polygon varieties." license = "MIT OR Apache-2.0" repository = "https://github.com/iShape-Rust/iOverlay" From 4a9b48f34d234d538b87e4d142dc85cee04e8ca3 Mon Sep 17 00:00:00 2001 From: Nail Sharipov Date: Sat, 28 Mar 2026 10:51:09 +0300 Subject: [PATCH 3/3] performance fix --- iOverlay/src/core/divide.rs | 2 +- iOverlay/src/core/extract.rs | 2 +- iOverlay/src/core/extract_ogc.rs | 2 +- iOverlay/src/split/solver_fragment.rs | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/iOverlay/src/core/divide.rs b/iOverlay/src/core/divide.rs index 39bbec7..bd1191a 100644 --- a/iOverlay/src/core/divide.rs +++ b/iOverlay/src/core/divide.rs @@ -45,7 +45,7 @@ impl ContourDecomposition for IntContour { .map(|(i, &p)| IdPoint::new(i, p)) .collect(); - id_points.sort_by(|p0, p1| p0.point.cmp(&p1.point).then_with(|| p0.id.cmp(&p1.id))); + id_points.sort_unstable_by(|p0, p1| p0.point.cmp(&p1.point).then_with(|| p0.id.cmp(&p1.id))); let mut p0 = id_points.first().unwrap().point; let mut anchors = Vec::new(); diff --git a/iOverlay/src/core/extract.rs b/iOverlay/src/core/extract.rs index 20870ef..8db879e 100644 --- a/iOverlay/src/core/extract.rs +++ b/iOverlay/src/core/extract.rs @@ -170,7 +170,7 @@ impl OverlayGraph<'_> { } if !anchors_already_sorted { - anchors.sort_by(|s0, s1| s0.v_segment.a.cmp(&s1.v_segment.a)); + anchors.sort_unstable_by(|s0, s1| s0.v_segment.a.cmp(&s1.v_segment.a)); } shapes.join_sorted_holes(holes, anchors, clockwise); diff --git a/iOverlay/src/core/extract_ogc.rs b/iOverlay/src/core/extract_ogc.rs index 07de181..0ab1ebc 100644 --- a/iOverlay/src/core/extract_ogc.rs +++ b/iOverlay/src/core/extract_ogc.rs @@ -168,7 +168,7 @@ impl OverlayGraph<'_> { } if !anchors_already_sorted { - anchors.sort_by(|s0, s1| s0.v_segment.a.cmp(&s1.v_segment.a)); + anchors.sort_unstable_by(|s0, s1| s0.v_segment.a.cmp(&s1.v_segment.a)); } shapes.join_sorted_holes(holes, anchors, is_main_dir_cw); diff --git a/iOverlay/src/split/solver_fragment.rs b/iOverlay/src/split/solver_fragment.rs index 24cef4e..01ac08a 100644 --- a/iOverlay/src/split/solver_fragment.rs +++ b/iOverlay/src/split/solver_fragment.rs @@ -108,7 +108,8 @@ impl SplitSolver { marks: Vec, } - let marks_capacity = self.marks.len() / buffer.groups.len(); + debug_assert!(!buffer.groups.is_empty(), "groups.len() >= 1"); + let marks_capacity = self.marks.capacity() / buffer.groups.len(); let results: Vec = buffer .groups