Changed: Improves flip algorithm with topology index#194
Conversation
Improves flip algorithm by introducing a topology index to efficiently check for duplicate cells and non-manifold facets. This avoids redundant scans of the triangulation data structure, especially during repair operations, by pre-computing and storing facet and cell signatures. This change is internal. Refs: perf/optimize-flips
WalkthroughAdds deterministic, seed-searchable benchmark input generation with per-count seeding and retry-policy-backed triangulation construction; introduces an internal FlipTopologyIndex to detect duplicate/non-manifold cells in k-move flips; and clarifies docs/tests that Cell/Vertex/Point/Tds do not require CoordinateScalar at the type level. Changes
Sequence Diagram(s)sequenceDiagram
participant CI as CI Runner
participant Bench as Bench Macro
participant Gen as Input Generator
participant DT as DelaunayTriangulation
participant Retry as RetryPolicy
rect rgba(200,200,255,0.5)
CI->>Bench: invoke CI performance suite
Bench->>Gen: derive base seed / per-count seed
Gen-->>Bench: sample points (with bounds)
Bench->>DT: DelaunayTriangulation::new_with_options(points, ConstructionOptions{RetryPolicy=Shuffled})
DT->>Retry: attempt construction (may shuffle/retry)
alt success
DT-->>Bench: triangulation ready
Bench-->>CI: report metrics / exit 0
else failure & seed-search enabled
Bench->>Bench: iterate candidate seeds up to limit
loop until found or limit
Bench->>Gen: generate points for candidate seed
Bench->>DT: try new_with_options(...)
DT->>Retry: retries...
end
alt found
Bench-->>CI: report found seed / exit 0
else not found
Bench-->>CI: report last seed and bounds / exit 1
end
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #194 +/- ##
==========================================
+ Coverage 63.05% 63.18% +0.12%
==========================================
Files 46 46
Lines 10119 10196 +77
==========================================
+ Hits 6381 6442 +61
- Misses 3738 3754 +16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/core/algorithms/flips.rs`:
- Around line 3895-3954: The function flip_would_create_nonmanifold_facets_any
sorts VertexKey values directly which mismatches the facet hash ordering used by
build_flip_topology_index; replace the current sort_unstable()/as_ffi extraction
with a call to sorted_vertex_key_values() to produce the sorted u64 key sequence
used for hashing (and use that sequence when building facet_values and computing
facet_hash against topology.candidate_facet_info); for tracing output
(facet_vertices) either reconstruct it from the sorted u64s or maintain a
parallel sorted VertexKey buffer using sort_unstable_by_key(|v|
v.data().as_ffi()) so logs remain meaningful.
🧹 Nitpick comments (1)
benches/ci_performance_suite.rs (1)
92-142: Seed search exits on the first successfulcount, not after validating all counts.The
std::process::exit(0)on line 130 terminates the entire process when any single(dim, count)succeeds. Since each count has its own derived seed (base + count), a seed that works forcount=10may fail forcount=50. If the goal is to find a base seed that works for all counts in a given dimension, the search would need to validate all counts before reporting success.This may be intentional (search per pair), but worth a brief comment in the code so future readers understand the intended usage.
Refactors the flip topology index to use `SmallBuffer` instead of `FastHashMap` for storing candidate cell signatures and facet info. This change optimizes memory usage and improves performance by leveraging the stack allocation and reduced overhead of `SmallBuffer` for small datasets, which are common in this context. Removes the 'internal' flag from the `CandidateFacetInfo` struct as boundary facets are no longer tracked. Refs: perf/optimize-flips
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@benches/ci_performance_suite.rs`:
- Line 28: The unresolved imports indicate ConstructionOptions, RetryPolicy, and
new_with_options are not publicly exported; either make them pub in
src/core/delaunay_triangulation.rs and add public re-exports (e.g., pub use
crate::core::delaunay_triangulation::{ConstructionOptions, RetryPolicy,
new_with_options};) in the crate's public API (lib.rs or prelude module), or
update the benchmark import to the actual public path where they are exported;
locate the symbols ConstructionOptions, RetryPolicy, and new_with_options in the
source and then either mark their definitions pub and re-export them from the
crate root/prelude or change the use line to the correct existing public module
path.
🧹 Nitpick comments (2)
benches/ci_performance_suite.rs (1)
140-151:std::process::exitbypasses destructors and Criterion cleanup.The seed-search helper exits the process directly, which skips all
Dropimplementations (Criterion state, temp files, etc.). The inline comments document the intent well, but consider returning early or usingpanic!instead, which would at least unwind the stack. Ifexitis preferred for clean exit codes, this is acceptable as-is given it's behind an opt-in env var.src/core/algorithms/flips.rs (1)
3793-3809: Hash-collision risk incandidate_facet_infodedup is negligible but undocumented.Lines 3804–3808 skip inserting a facet entry when a matching hash already exists, and lines 3874–3878 use
binary_search_by_keyon the hash. If two distinct internal facets were to produce the samestable_hash_u64_slicevalue, one facet would be silently dropped—potentially causing a false negative in the non-manifold check (or a false positive if an unrelated existing facet collides with the tracked hash).The probability is astronomically low (~2⁻⁶⁴ per pair) given FNV on short sorted
u64slices, so this is safe in practice. A brief inline comment noting the intentional hash-only comparison (no vertex-level tiebreak) would help future readers understand the trade-off.
Refactors the flip algorithm to use more efficient data structures (SmallBuffer instead of FastHashMap/Vec) and hashing techniques (hash-only dedup) to improve performance. Also refactors benchmark seed search to avoid `std::process::exit`. These changes significantly reduce the time spent in the flip algorithm, leading to faster triangulation construction. (internal) Refs: perf/optimize-flips
Improves flip algorithm by introducing a topology index to efficiently check for duplicate cells and non-manifold facets. This avoids redundant scans of the triangulation data structure, especially during repair operations, by pre-computing and storing facet and cell signatures. This change is internal.
Refs: perf/optimize-flips