1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
use ;
use crateFacetHandle;
use crate;
// =============================================================================
// ALGORITHM-SPECIFIC BUFFER TYPES
// =============================================================================
/// Size constant for operations that may affect multiple cells during cleanup.
/// 16 provides generous headroom for duplicate removal and topology repair operations.
///
/// This constant is publicly exposed to allow external modules to derive buffer sizes
/// from it, ensuring consistent sizing across the codebase.
pub const CLEANUP_OPERATION_BUFFER_SIZE: usize = 16;
/// Size constant for operations that work with a small number of valid cells.
/// 4 is sufficient since valid facets are shared by at most 2 cells, with some headroom.
const SMALL_CELL_OPERATION_BUFFER_SIZE: usize = 4;
/// Collection for tracking cells to remove during cleanup operations.
/// Most cleanup operations affect a small number of cells.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 16 cells (covers most cleanup scenarios)
/// - **Use Case**: Duplicate cell removal, invalid facet cleanup
/// - **Performance**: Avoids heap allocation for typical cleanup operations
pub type CellRemovalBuffer = ;
/// Collection for tracking Delaunay violations during iterative refinement.
/// Most violation checks find a small number of violating cells.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 16 cells (covers most violation scenarios)
/// - **Use Case**: Iterative cavity refinement, Delaunay validation
/// - **Performance**: Avoids heap allocation in hot paths during insertion
/// - **Typical Size**: 0-4 violations in well-conditioned triangulations
pub type ViolationBuffer = ;
/// Collection for tracking cell keys during insertion operations.
/// Most insertion operations create a small number of cells.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 16 cells (covers most insertion scenarios)
/// - **Use Case**: Cavity-based insertion, cell creation tracking
/// - **Performance**: Avoids heap allocation during cell creation
/// - **Typical Size**: 4-8 cells in well-conditioned triangulations (D+1 for simple cavity)
pub type CellKeyBuffer = ;
/// Collection for tracking bad cells (Delaunay violations) during insertion.
/// Bad cells are those whose circumsphere contains the newly inserted point.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 16 cells (covers most cavity scenarios)
/// - **Use Case**: Bowyer-Watson algorithm, `find_bad_cells()` return type
/// - **Performance**: Avoids heap allocation in hot path during point insertion
/// - **Typical Size**: 1-8 cells in well-conditioned triangulations
///
/// # Usage
///
/// This buffer is used as the return type for `find_bad_cells()` and related methods.
/// The capacity of 16 is generous for typical Delaunay cavities while remaining stack-allocated.
///
/// # Examples
///
/// ```rust
/// use delaunay::core::collections::BadCellBuffer;
///
/// // Accumulate bad cells during insertion
/// let mut bad_cells: BadCellBuffer = BadCellBuffer::new();
/// assert!(bad_cells.is_empty());
/// ```
pub type BadCellBuffer = ;
/// Collection for tracking valid cells during facet sharing fixes.
/// Most invalid sharing situations involve only a few cells per facet.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 4 cells (more than enough for valid facets)
/// - **Use Case**: Facet validation, topology repair
/// - **Performance**: Stack-only for typical geometric repair operations
pub type ValidCellsBuffer = ;
/// Buffer for storing facet information during boundary analysis.
/// Sized for typical cell operations (D+1 facets per cell).
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to `MAX_PRACTICAL_DIMENSION_SIZE` facet handles
/// - **Use Case**: Boundary analysis, facet enumeration
/// - **Performance**: Handles cells up to 7D on stack
/// - **Type Safety**: Uses `FacetHandle` instead of raw tuples to prevent errors
///
/// # Type Safety
///
/// This buffer uses `FacetHandle` rather than `(CellKey, FacetIndex)` tuples to:
/// - Prevent accidental swapping of `cell_key` and `facet_index`
/// - Make the API more self-documenting
/// - Enable future extensions without breaking changes
pub type FacetInfoBuffer = ;
/// Buffer for storing cavity boundary facets during insertion/removal operations.
///
/// This is used by cavity extraction and filling routines. Inline capacity 64 avoids heap
/// allocation for typical cavities while still allowing growth for large conflict regions.
pub type CavityBoundaryBuffer = ;
/// Buffer for storing cells that share a facet.
/// Facets are shared by at most 2 cells (boundary=1, interior=2).
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Exactly 2 cells (no heap allocation for valid triangulations)
/// - **Use Case**: Facet-to-cells mapping validation, cavity boundary detection
/// - **Performance**: Eliminates heap allocation when invariant holds (≤2 cells per facet)
/// - **Memory Efficiency**: 2 × 8 bytes = 16 bytes on stack per facet
///
/// # Invariant
///
/// Valid triangulations have the following facet sharing invariants:
/// - **Boundary facets**: Shared by exactly 1 cell (hull facets)
/// - **Interior facets**: Shared by exactly 2 cells (adjacent cells)
/// - **Invalid**: Shared by >2 cells (indicates TDS corruption)
///
/// # Examples
///
/// ```rust
/// use delaunay::core::collections::FacetSharingCellsBuffer;
///
/// let mut sharing_cells: FacetSharingCellsBuffer = FacetSharingCellsBuffer::new();
/// assert!(sharing_cells.is_empty());
/// ```
pub type FacetSharingCellsBuffer = ;
// =============================================================================
// SEMANTIC SIZE CONSTANTS AND TYPE ALIASES
// =============================================================================
/// Buffer sized for vertex collections in D-dimensional simplices.
/// A D-dimensional simplex has D+1 vertices, so this handles up to 7D simplices on stack.
///
/// # Use Cases
/// - Cell vertex operations
/// - Simplex construction
/// - Geometric predicate vertex lists
pub type SimplexVertexBuffer<T> = ;
/// Buffer sized for UUID collections in vertex operations.
/// Optimized for storing vertex UUIDs from a single simplex (D+1 UUIDs).
///
/// # Use Cases
/// - Duplicate cell detection
/// - Vertex uniqueness checks
/// - Cell vertex UUID collections
pub type VertexUuidBuffer = ;
/// Buffer sized for `VertexKey` collections in validation and internal operations.
/// Handles vertex keys from a single D-dimensional simplex.
///
/// # Use Cases
/// - Validation algorithms
/// - Internal vertex key tracking
/// - Cell vertex key collections
pub type VertexKeyBuffer = ;
/// Buffer for storing cell neighbors (D+1 neighbors for a D-dimensional cell).
/// Uses stack allocation for typical dimensions (2D-7D).
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: D+1 neighbors fit on stack for D ≤ 7
/// - **Use Case**: Neighbor queries, neighbor assignment, validation
/// - **Performance**: Avoids heap allocation in 90%+ of cases
/// - **Memory Layout**: Better cache locality than heap-allocated Vec
///
/// # Examples
///
/// ```rust
/// use delaunay::core::collections::NeighborBuffer;
/// use delaunay::core::triangulation_data_structure::CellKey;
///
/// let mut neighbors: NeighborBuffer<Option<CellKey>> = NeighborBuffer::new();
/// assert!(neighbors.is_empty());
/// ```
pub type NeighborBuffer<T> = ;
/// Buffer for vertex key collections from a single cell (D+1 vertices).
/// Avoids heap allocation for typical triangulation dimensions.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: D+1 vertex keys fit on stack for D ≤ 7
/// - **Use Case**: Cell vertex storage, validation, geometric operations
/// - **Performance**: Eliminates heap allocation for typical dimensions
/// - **Ordering**: Preserves vertex order for positional semantics
pub type CellVertexBuffer = ;
/// Buffer for vertex UUID collections from a single cell (D+1 vertex UUIDs).
/// Uses stack allocation to avoid heap overhead for cell operations.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: D+1 vertex UUIDs fit on stack for D ≤ 7
/// - **Use Case**: Extracting vertex UUIDs from a cell, validation, duplicate detection
/// - **Performance**: Avoids allocation for temporary UUID collections
/// - **Memory Efficiency**: For D=7, D+1=8 UUIDs → 16 bytes × 8 = 128 bytes on stack
pub type CellVertexUuidBuffer = ;
/// Buffer sized for Point collections in geometric operations.
/// Generic over coordinate type T and dimension D, with practical size limit.
///
/// # Use Cases
/// - Geometric predicate operations
/// - Simplex coordinate collections
/// - Temporary point storage during algorithms
pub type GeometricPointBuffer<T, const D: usize> =
;
/// Size constant for batch point processing operations.
/// 16 provides sufficient capacity for typical geometric algorithm batches.
const BATCH_PROCESSING_BUFFER_SIZE: usize = 16;
/// Temporary buffer for storing points during geometric operations.
/// Sized for typical batch processing operations.
///
/// # Optimization Rationale
///
/// - **Stack Allocation**: Up to 16 points for batch operations
/// - **Generic Dimension**: Works with any coordinate type and dimension
/// - **Use Case**: Point processing, geometric transformations
/// - **Performance**: Avoids allocation for small point batches
pub type PointBuffer<T, const D: usize> = ;