nc-gcode-interpreter 0.2.4__tar.gz → 0.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/CHANGELOG.md +14 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/Cargo.lock +1 -1
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/Cargo.toml +1 -1
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/PKG-INFO +1 -1
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/output.rs +83 -13
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/.github/workflows/build-and-release.yml +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/.gitignore +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/CONTRIBUTING.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/Development.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/LICENSE +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/README.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/TODO.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/docs/resumable-interpretation-design.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/docs/sinumerik-execution-model.md +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/actual_position.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/actual_position.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/arc.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/arc.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/arrays.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/arrays.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/axis_index_assignment.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/axis_index_assignment.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/basic_math.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/basic_math.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case_insensitive_variables.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case_insensitive_variables.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/custom_vars.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/custom_vars.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/def_string.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/def_string.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/defaults.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/defaults.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/edge_cases.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/edge_cases.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/flattening/flatten_demo.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/flattening/flatten_demo_flattened.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/flattening/flatten_demo_raw.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/for_loop.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/for_loop.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/function_calls.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/function_calls.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/goto.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/goto.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/if_statement.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/if_statement.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/increment.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/increment.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/logic_operators.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/logic_operators.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/loop.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/loop.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/multiple_m_codes.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/multiple_m_codes.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/precedence.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/precedence.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/r_param.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/r_param.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/repeat.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/repeat.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/simple.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/simple.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/spline.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/spline.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/tool.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/tool.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans2.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans2.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans_ic.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans_ic.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans_reset.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trans_reset.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trig.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/trig.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/variables.csv +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/variables.mpf +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/ggroups/generate_g_commands.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/pyproject.toml +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/example/minimal.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/example/streaming.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/__init__.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/_internal.pyi +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/cli.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/ggroups.json +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/py.typed +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/viz.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_arithmetic_functions.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_batch_variables.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_batches.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_diagnostics.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_expected_output.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_field_defects.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_flags.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_flatten.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_g_groups.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_g_vocabulary.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_jumps.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_real_comparisons.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_stage1.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_streaming.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_structured_errors.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_unsupported.py +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/rustfmt.toml +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/errors.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/flatten.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/grammar.pest +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/interpret_rules.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/interpreter.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/lib.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/line_driver.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/main.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/modal_groups.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/state.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/structure_scan.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/types.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/src/vm.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/tests/cli.rs +0 -0
- {nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/uv.lock +0 -0
|
@@ -4,6 +4,20 @@ Notable changes to **nc-gcode-interpreter**. The format loosely follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/); versions are git tags,
|
|
5
5
|
released to PyPI.
|
|
6
6
|
|
|
7
|
+
## [v0.2.5] - 2026-07-08
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Interpreter throughput on the DataFrame/batch path: the per-output-row `Row`
|
|
12
|
+
allocations are now recycled instead of freed. Profiling the 1.1 GB → DataFrame
|
|
13
|
+
conversion showed ~50% of CPU in the system allocator, dominated by allocating
|
|
14
|
+
and freeing each of the 22M rows' cell buffers. After a batch is built its rows
|
|
15
|
+
are cleared (capacity retained) into a pool and handed back to the interpreter
|
|
16
|
+
to refill, bounding live row allocations to ~2× the batch size instead of the
|
|
17
|
+
whole-file row count. Output is byte-identical; the streaming (`nc_to_rows`)
|
|
18
|
+
and in-memory collect paths are unchanged. ~10% off end-to-end on the large
|
|
19
|
+
real-world program (#61).
|
|
20
|
+
|
|
7
21
|
## [v0.2.4] - 2026-07-08
|
|
8
22
|
|
|
9
23
|
### Changed
|
|
@@ -82,6 +82,13 @@ impl CellMap {
|
|
|
82
82
|
None
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/// Empty the cells, retaining the backing allocation so a recycled row can
|
|
86
|
+
/// be refilled without a fresh heap allocation (see [`Row::reset_for_reuse`]).
|
|
87
|
+
#[inline]
|
|
88
|
+
pub fn clear(&mut self) {
|
|
89
|
+
self.entries.clear();
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
#[inline]
|
|
86
93
|
pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
|
|
87
94
|
self.entries.iter_mut().find(|(k, _)| *k == key).map(|(_, v)| v)
|
|
@@ -131,6 +138,20 @@ pub struct Row {
|
|
|
131
138
|
pub variable_changes: Vec<(String, f64)>,
|
|
132
139
|
}
|
|
133
140
|
|
|
141
|
+
impl Row {
|
|
142
|
+
/// Empty this row for reuse as the next `current`, retaining both the cells
|
|
143
|
+
/// and variable-change allocations. On the batch path a finished row's
|
|
144
|
+
/// buffers are consumed into the columnar batch and then recycled here,
|
|
145
|
+
/// which collapses the per-row heap alloc/free (~22M on the 1.1 GB file,
|
|
146
|
+
/// the dominant allocator cost) into a small pool cycled batch-to-batch.
|
|
147
|
+
#[inline]
|
|
148
|
+
pub fn reset_for_reuse(&mut self) {
|
|
149
|
+
self.line_no = 0;
|
|
150
|
+
self.cells.clear();
|
|
151
|
+
self.variable_changes.clear();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
134
155
|
/// Sparse side-table of variable-change events for the batch path, mirroring
|
|
135
156
|
/// what the streaming `nc_to_rows` yields per row as `variable_changes`. Stored
|
|
136
157
|
/// columnar (struct-of-arrays) so it converts to an Arrow table cheaply:
|
|
@@ -205,6 +226,10 @@ pub struct BatchStreamSink {
|
|
|
205
226
|
sender: std::sync::mpsc::SyncSender<Table>,
|
|
206
227
|
builder: BatchBuilder,
|
|
207
228
|
buffer: Vec<Row>,
|
|
229
|
+
/// Emptied rows kept for reuse: after a batch is built the buffered rows'
|
|
230
|
+
/// allocations are cleared (not freed) into this pool, and `accept` hands
|
|
231
|
+
/// them back to the interpreter to refill instead of allocating fresh.
|
|
232
|
+
recycle: Vec<Row>,
|
|
208
233
|
batch_size: usize,
|
|
209
234
|
/// Whether to accumulate variable-change events (opt-in `include_variables`).
|
|
210
235
|
record_variables: bool,
|
|
@@ -226,7 +251,7 @@ impl BatchStreamSink {
|
|
|
226
251
|
/// rows have accumulated. Variable-only rows carry no output cells and are
|
|
227
252
|
/// dropped from the batch table, but their variable changes are still
|
|
228
253
|
/// recorded into the sparse event log when `record_variables` is on.
|
|
229
|
-
fn accept(&mut self, row: Row) -> Result<
|
|
254
|
+
fn accept(&mut self, mut row: Row) -> Result<Option<Row>, ParsingError> {
|
|
230
255
|
if self.record_variables {
|
|
231
256
|
for (name, value) in &row.variable_changes {
|
|
232
257
|
let id = match self.name_ids.get(name) {
|
|
@@ -246,15 +271,20 @@ impl BatchStreamSink {
|
|
|
246
271
|
self.events.value.push(*value);
|
|
247
272
|
}
|
|
248
273
|
}
|
|
274
|
+
// A variable-only row carries no output cell: it is not buffered, so hand
|
|
275
|
+
// its (cleared) allocation straight back for reuse.
|
|
249
276
|
if row.cells.is_empty() {
|
|
250
|
-
|
|
277
|
+
row.reset_for_reuse();
|
|
278
|
+
return Ok(Some(row));
|
|
251
279
|
}
|
|
252
280
|
self.output_row_count += 1;
|
|
253
281
|
self.buffer.push(row);
|
|
254
282
|
if self.buffer.len() >= self.batch_size {
|
|
255
283
|
self.emit()?;
|
|
256
284
|
}
|
|
257
|
-
|
|
285
|
+
// Hand back a pooled row (refilled after the last emit) so the caller
|
|
286
|
+
// refills a retained allocation instead of allocating a fresh one.
|
|
287
|
+
Ok(self.recycle.pop())
|
|
258
288
|
}
|
|
259
289
|
|
|
260
290
|
/// Send the accumulated variable-change events once, at finish. A no-op when
|
|
@@ -272,8 +302,20 @@ impl BatchStreamSink {
|
|
|
272
302
|
if self.buffer.is_empty() {
|
|
273
303
|
return Ok(());
|
|
274
304
|
}
|
|
275
|
-
|
|
305
|
+
// Take the buffered rows out to build the batch, then recycle their
|
|
306
|
+
// allocations: `build_batch` only borrows the rows (it copies each cell
|
|
307
|
+
// value into the columnar builders), so once it returns the row buffers
|
|
308
|
+
// are free to be cleared and pooled rather than dropped.
|
|
309
|
+
let mut rows = std::mem::take(&mut self.buffer);
|
|
276
310
|
let table = self.builder.build_batch(&rows);
|
|
311
|
+
self.recycle.reserve(rows.len());
|
|
312
|
+
for mut row in rows.drain(..) {
|
|
313
|
+
row.reset_for_reuse();
|
|
314
|
+
self.recycle.push(row);
|
|
315
|
+
}
|
|
316
|
+
// `rows` is now empty but keeps its `Vec<Row>` capacity - reinstate it as
|
|
317
|
+
// the buffer so the outer vector is not reallocated each batch either.
|
|
318
|
+
self.buffer = rows;
|
|
277
319
|
self.sender.send(table).map_err(|_| ParsingError::StreamClosed)
|
|
278
320
|
}
|
|
279
321
|
}
|
|
@@ -362,6 +404,7 @@ impl OutputRows {
|
|
|
362
404
|
sender,
|
|
363
405
|
builder: BatchBuilder::new(disable_forward_fill).with_line_numbers(emit_line_no),
|
|
364
406
|
buffer: Vec::new(),
|
|
407
|
+
recycle: Vec::new(),
|
|
365
408
|
batch_size,
|
|
366
409
|
record_variables,
|
|
367
410
|
events_sender,
|
|
@@ -416,32 +459,53 @@ impl OutputRows {
|
|
|
416
459
|
}
|
|
417
460
|
}
|
|
418
461
|
|
|
419
|
-
///
|
|
420
|
-
///
|
|
421
|
-
|
|
462
|
+
/// Return a recycled row to the sink's pool. Used when a single `deliver`
|
|
463
|
+
/// yields more recycled rows than the one the caller can reuse as `current`
|
|
464
|
+
/// (the flattener fans one block out to many rows): the surplus goes back to
|
|
465
|
+
/// the pool instead of being freed, so recycling stays effective on
|
|
466
|
+
/// flattened paths too. A no-op for the non-recycling sinks.
|
|
467
|
+
fn reclaim(&mut self, row: Row) {
|
|
468
|
+
if let RowSink::Batch(sink) = &mut self.sink {
|
|
469
|
+
sink.recycle.push(row);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/// Route a row to the sink, passing it through the flattener first when one
|
|
474
|
+
/// is installed, and returning an emptied row the sink no longer needs
|
|
475
|
+
/// (batch path) so the caller can reuse its allocation as the next
|
|
476
|
+
/// `current`. `None` when nothing is available to recycle.
|
|
477
|
+
fn deliver(&mut self, row: Row) -> Result<Option<Row>, ParsingError> {
|
|
422
478
|
if let Some(mut flattener) = self.flattener.take() {
|
|
423
479
|
let mut flattened = Vec::new();
|
|
424
480
|
flattener.push(row, &mut flattened);
|
|
425
481
|
self.flattener = Some(flattener);
|
|
482
|
+
// Keep one recycled row for the caller to reuse; hand any others the
|
|
483
|
+
// sink returns this call straight back to the pool so they are not
|
|
484
|
+
// freed (a flattened block delivers many rows in one `deliver`).
|
|
485
|
+
let mut recycled = None;
|
|
426
486
|
for row in flattened {
|
|
427
|
-
self.deliver_to_sink(row)
|
|
487
|
+
if let Some(r) = self.deliver_to_sink(row)? {
|
|
488
|
+
if let Some(prev) = recycled.replace(r) {
|
|
489
|
+
self.reclaim(prev);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
428
492
|
}
|
|
429
|
-
return Ok(
|
|
493
|
+
return Ok(recycled);
|
|
430
494
|
}
|
|
431
495
|
self.deliver_to_sink(row)
|
|
432
496
|
}
|
|
433
497
|
|
|
434
498
|
/// Route a finished row to the sink: collected, streamed row-at-a-time, or
|
|
435
499
|
/// fed to the worker-side batch producer.
|
|
436
|
-
fn deliver_to_sink(&mut self, row: Row) -> Result<
|
|
500
|
+
fn deliver_to_sink(&mut self, row: Row) -> Result<Option<Row>, ParsingError> {
|
|
437
501
|
match &mut self.sink {
|
|
438
502
|
RowSink::Collect(rows) => {
|
|
439
503
|
rows.push(row);
|
|
440
|
-
Ok(
|
|
504
|
+
Ok(None)
|
|
441
505
|
}
|
|
442
506
|
// The receiver hung up: the consumer stopped iterating. Abort
|
|
443
507
|
// interpretation instead of running the rest of the program.
|
|
444
|
-
RowSink::Stream(sender) => sender.send(row).map_err(|_| ParsingError::StreamClosed),
|
|
508
|
+
RowSink::Stream(sender) => sender.send(row).map(|_| None).map_err(|_| ParsingError::StreamClosed),
|
|
445
509
|
RowSink::Batch(sink) => sink.accept(row),
|
|
446
510
|
}
|
|
447
511
|
}
|
|
@@ -464,7 +528,13 @@ impl OutputRows {
|
|
|
464
528
|
self.warned_g91 = true;
|
|
465
529
|
}
|
|
466
530
|
}
|
|
467
|
-
|
|
531
|
+
// `mem::take` above left `current` as an empty (unallocated) default; if
|
|
532
|
+
// the sink handed back a pooled row, adopt its retained allocation for
|
|
533
|
+
// the next block instead of allocating fresh on the first cell insert.
|
|
534
|
+
if let Some(recycled) = self.deliver(row)? {
|
|
535
|
+
self.current = recycled;
|
|
536
|
+
}
|
|
537
|
+
Ok(())
|
|
468
538
|
}
|
|
469
539
|
|
|
470
540
|
/// Begin the row for the block at `line_no`, flushing the previous row.
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/.github/workflows/build-and-release.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/docs/resumable-interpretation-design.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/axis_index_assignment.csv
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/axis_index_assignment.mpf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case_insensitive_variables.csv
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/case_insensitive_variables.mpf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/flattening/flatten_demo.mpf
RENAMED
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/examples/flattening/flatten_demo_raw.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/__init__.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/_internal.pyi
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/cli.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/ggroups.json
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/py.typed
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/nc_gcode_interpreter/viz.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_arithmetic_functions.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_batch_variables.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_expected_output.py
RENAMED
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_field_defects.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_real_comparisons.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nc_gcode_interpreter-0.2.4 → nc_gcode_interpreter-0.2.5}/python/tests/test_structured_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|