chronaxis 0.1.0.dev0__py3-none-any.whl
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.
- chronaxis/__init__.py +72 -0
- chronaxis/__main__.py +12 -0
- chronaxis/analysis_cli.py +181 -0
- chronaxis/batch/__init__.py +14 -0
- chronaxis/batch/api.py +46 -0
- chronaxis/batch/cli.py +48 -0
- chronaxis/batch/config.py +37 -0
- chronaxis/batch/models.py +202 -0
- chronaxis/batch/process_transport.py +149 -0
- chronaxis/batch/process_tree.py +72 -0
- chronaxis/batch/publication.py +41 -0
- chronaxis/batch/runner.py +236 -0
- chronaxis/batch/templates.py +42 -0
- chronaxis/can_dependencies.py +42 -0
- chronaxis/cli.py +193 -0
- chronaxis/configuration/__init__.py +46 -0
- chronaxis/configuration/cli.py +41 -0
- chronaxis/configuration/diagnostics.py +107 -0
- chronaxis/configuration/explanation.py +233 -0
- chronaxis/configuration/file_tools.py +140 -0
- chronaxis/configuration/imports.py +144 -0
- chronaxis/configuration/initialization.py +36 -0
- chronaxis/configuration/json_parser.py +114 -0
- chronaxis/configuration/models.py +74 -0
- chronaxis/configuration/origins.py +90 -0
- chronaxis/configuration/overrides.py +55 -0
- chronaxis/configuration/resolution.py +150 -0
- chronaxis/configuration/template_catalog.py +68 -0
- chronaxis/configuration/templates/batch/analysis-annotated.yaml +18 -0
- chronaxis/configuration/templates/batch/analysis-minimal.yaml +18 -0
- chronaxis/configuration/templates/batch/annotated.yaml +6 -0
- chronaxis/configuration/templates/batch/minimal.yaml +6 -0
- chronaxis/configuration/templates/can-asc/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-asc/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-blf/annotated.yaml +18 -0
- chronaxis/configuration/templates/can-blf/minimal.yaml +18 -0
- chronaxis/configuration/templates/can-export/annotated.yaml +23 -0
- chronaxis/configuration/templates/can-export/minimal.yaml +23 -0
- chronaxis/configuration/templates/catalog.json +233 -0
- chronaxis/configuration/templates/charge-session/annotated.yaml +38 -0
- chronaxis/configuration/templates/charge-session/minimal.yaml +38 -0
- chronaxis/configuration/templates/command-response/annotated.yaml +32 -0
- chronaxis/configuration/templates/command-response/minimal.yaml +36 -0
- chronaxis/configuration/templates/fault-window/annotated.yaml +25 -0
- chronaxis/configuration/templates/fault-window/minimal.yaml +27 -0
- chronaxis/configuration/templates/ini-mapping/annotated.yaml +20 -0
- chronaxis/configuration/templates/ini-mapping/minimal.yaml +20 -0
- chronaxis/configuration/templates/raw-can-csv/annotated.yaml +34 -0
- chronaxis/configuration/templates/raw-can-csv/minimal.yaml +35 -0
- chronaxis/configuration/templates/shared/charge-session.asc +5 -0
- chronaxis/configuration/templates/shared/command-response.asc +8 -0
- chronaxis/configuration/templates/shared/fault-window.asc +5 -0
- chronaxis/configuration/templates/shared/power.asc +7 -0
- chronaxis/configuration/templates/shared/sample.asc +6 -0
- chronaxis/configuration/templates/shared/sample.blf +0 -0
- chronaxis/configuration/templates/shared/sample.csv +5 -0
- chronaxis/configuration/templates/shared/sample.dbc +11 -0
- chronaxis/configuration/templates/shared/signals.csv +6 -0
- chronaxis/configuration/templates/shared/source.ini +5 -0
- chronaxis/configuration/templates/shared/stability.asc +9 -0
- chronaxis/configuration/templates/shared/teaching.dbc +27 -0
- chronaxis/configuration/templates/shared/threshold.asc +7 -0
- chronaxis/configuration/templates/signal-csv/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-csv/minimal.yaml +27 -0
- chronaxis/configuration/templates/signal-export/annotated.yaml +27 -0
- chronaxis/configuration/templates/signal-export/minimal.yaml +29 -0
- chronaxis/configuration/templates/stability/annotated.yaml +35 -0
- chronaxis/configuration/templates/stability/minimal.yaml +35 -0
- chronaxis/configuration/templates/threshold/annotated.yaml +22 -0
- chronaxis/configuration/templates/threshold/minimal.yaml +22 -0
- chronaxis/configuration/yaml_parser.py +125 -0
- chronaxis/core/__init__.py +71 -0
- chronaxis/core/binding.py +449 -0
- chronaxis/core/calculation_series_join.py +106 -0
- chronaxis/core/calculations.py +435 -0
- chronaxis/core/calculations_memory_numpy.py +136 -0
- chronaxis/core/calculations_memory_reference.py +165 -0
- chronaxis/core/calculations_numpy.py +298 -0
- chronaxis/core/calculations_reference.py +294 -0
- chronaxis/core/condition_evidence.py +182 -0
- chronaxis/core/conditional_integral_result.py +43 -0
- chronaxis/core/conditional_integral_terms.py +146 -0
- chronaxis/core/conditional_integral_terms_numpy.py +148 -0
- chronaxis/core/conditional_integral_terms_reference.py +111 -0
- chronaxis/core/conditional_time_reduction.py +118 -0
- chronaxis/core/conditional_time_reduction_numpy.py +223 -0
- chronaxis/core/conditional_time_reduction_reference.py +213 -0
- chronaxis/core/declarations.py +192 -0
- chronaxis/core/decoded_binding.py +197 -0
- chronaxis/core/direct_message.py +387 -0
- chronaxis/core/export_interpolation.py +54 -0
- chronaxis/core/expression.py +642 -0
- chronaxis/core/expression_numpy.py +314 -0
- chronaxis/core/expression_reference.py +272 -0
- chronaxis/core/integral_result.py +53 -0
- chronaxis/core/integral_sum.py +77 -0
- chronaxis/core/integral_sum_numpy.py +224 -0
- chronaxis/core/integral_sum_reference.py +148 -0
- chronaxis/core/integral_terms.py +119 -0
- chronaxis/core/integral_terms_numpy.py +127 -0
- chronaxis/core/integral_terms_reference.py +91 -0
- chronaxis/core/mean_weights_numpy.py +29 -0
- chronaxis/core/mean_weights_reference.py +27 -0
- chronaxis/core/message_binding.py +305 -0
- chronaxis/core/models.py +485 -0
- chronaxis/core/normalize_numpy.py +396 -0
- chronaxis/core/numeric.py +472 -0
- chronaxis/core/numeric_numpy.py +440 -0
- chronaxis/core/record_intervals.py +115 -0
- chronaxis/core/sample_reduction.py +161 -0
- chronaxis/core/sample_reduction_numpy.py +160 -0
- chronaxis/core/sample_reduction_reference.py +154 -0
- chronaxis/core/selection.py +74 -0
- chronaxis/core/sequence.py +160 -0
- chronaxis/core/sequence_reference.py +248 -0
- chronaxis/core/stability.py +249 -0
- chronaxis/core/start_end.py +169 -0
- chronaxis/core/state.py +494 -0
- chronaxis/core/state_numpy.py +296 -0
- chronaxis/core/temporal.py +373 -0
- chronaxis/core/temporal_clock.py +25 -0
- chronaxis/core/temporal_memory_numpy.py +163 -0
- chronaxis/core/temporal_memory_reference.py +161 -0
- chronaxis/core/temporal_numpy.py +345 -0
- chronaxis/core/temporal_reference.py +304 -0
- chronaxis/core/time_reduction.py +190 -0
- chronaxis/core/time_reduction_numpy.py +205 -0
- chronaxis/core/time_reduction_reference.py +203 -0
- chronaxis/core/types.py +105 -0
- chronaxis/core/units.py +81 -0
- chronaxis/core/validation.py +94 -0
- chronaxis/core/window_delta.py +123 -0
- chronaxis/core/window_delta_numpy.py +78 -0
- chronaxis/core/window_delta_reference.py +69 -0
- chronaxis/core/windows.py +224 -0
- chronaxis/core/windows_numpy.py +78 -0
- chronaxis/core/windows_reference.py +61 -0
- chronaxis/execution/__init__.py +6 -0
- chronaxis/execution/batch_signal_groups.py +122 -0
- chronaxis/execution/bindings.py +296 -0
- chronaxis/execution/boundaries.py +568 -0
- chronaxis/execution/calculation_blocks.py +338 -0
- chronaxis/execution/calculation_values.py +55 -0
- chronaxis/execution/can_batch_reader.py +356 -0
- chronaxis/execution/can_reader.py +948 -0
- chronaxis/execution/can_reference_template.py +61 -0
- chronaxis/execution/condition_evidence.py +370 -0
- chronaxis/execution/conditional_integral_facts.py +310 -0
- chronaxis/execution/conditional_integral_reduction.py +216 -0
- chronaxis/execution/csv_observation.py +524 -0
- chronaxis/execution/csv_reader.py +662 -0
- chronaxis/execution/current_message_calculation.py +225 -0
- chronaxis/execution/driver_expression.py +274 -0
- chronaxis/execution/expressions.py +618 -0
- chronaxis/execution/frame_capture.py +245 -0
- chronaxis/execution/groups.py +236 -0
- chronaxis/execution/historical_conditional_blocks.py +264 -0
- chronaxis/execution/historical_conditional_integral.py +226 -0
- chronaxis/execution/historical_conditional_time_calculation.py +368 -0
- chronaxis/execution/historical_integral.py +219 -0
- chronaxis/execution/historical_observation.py +372 -0
- chronaxis/execution/historical_sample_calculation.py +338 -0
- chronaxis/execution/historical_selection_rows.py +300 -0
- chronaxis/execution/historical_time_calculation.py +341 -0
- chronaxis/execution/history.py +572 -0
- chronaxis/execution/history_records.py +225 -0
- chronaxis/execution/hold.py +448 -0
- chronaxis/execution/integral_facts.py +311 -0
- chronaxis/execution/integral_reduction.py +216 -0
- chronaxis/execution/legacy_frame_samples.py +94 -0
- chronaxis/execution/memory_reader.py +247 -0
- chronaxis/execution/message_bindings.py +293 -0
- chronaxis/execution/message_delivery.py +37 -0
- chronaxis/execution/observed_ingestion.py +551 -0
- chronaxis/execution/raw_signal_groups.py +192 -0
- chronaxis/execution/record_alarm_duration.py +114 -0
- chronaxis/execution/record_delta_condition.py +167 -0
- chronaxis/execution/record_diagnostics.py +87 -0
- chronaxis/execution/record_event_durations.py +143 -0
- chronaxis/execution/record_export_samples.py +94 -0
- chronaxis/execution/record_exports.py +155 -0
- chronaxis/execution/record_integral.py +196 -0
- chronaxis/execution/record_point_buffer.py +101 -0
- chronaxis/execution/record_rule_timeline.py +344 -0
- chronaxis/execution/record_sample.py +46 -0
- chronaxis/execution/record_sample_series.py +29 -0
- chronaxis/execution/record_scope_calculations.py +290 -0
- chronaxis/execution/record_selection.py +62 -0
- chronaxis/execution/record_sequences.py +199 -0
- chronaxis/execution/record_session_calculations.py +778 -0
- chronaxis/execution/record_signal_export.py +133 -0
- chronaxis/execution/record_source_cursor.py +295 -0
- chronaxis/execution/record_time_calculation.py +322 -0
- chronaxis/execution/record_time_indexes.py +143 -0
- chronaxis/execution/record_value_history.py +160 -0
- chronaxis/execution/record_windows.py +229 -0
- chronaxis/execution/required_expression.py +52 -0
- chronaxis/execution/retained_metadata.py +71 -0
- chronaxis/execution/run_session.py +402 -0
- chronaxis/execution/scanned_signal_proof.py +550 -0
- chronaxis/execution/signal_validity.py +40 -0
- chronaxis/execution/state.py +280 -0
- chronaxis/execution/temporal_buffer.py +508 -0
- chronaxis/execution/text_can_reader.py +359 -0
- chronaxis/execution/timeline.py +309 -0
- chronaxis/execution/timeline_multi.py +415 -0
- chronaxis/execution/window_delta_events.py +220 -0
- chronaxis/execution/window_replay.py +350 -0
- chronaxis/execution/windows.py +173 -0
- chronaxis/guide/README.md +70 -0
- chronaxis/guide/api/AnalysisError.md +14 -0
- chronaxis/guide/api/AnalysisPlan.md +96 -0
- chronaxis/guide/api/AnalysisResult.md +398 -0
- chronaxis/guide/api/AnalysisRunner.md +155 -0
- chronaxis/guide/api/BatchJob.md +19 -0
- chronaxis/guide/api/BatchJobResult.md +61 -0
- chronaxis/guide/api/BatchPlan.md +48 -0
- chronaxis/guide/api/BatchReport.md +108 -0
- chronaxis/guide/api/BatchRunner.md +84 -0
- chronaxis/guide/api/OutputManifest.md +23 -0
- chronaxis/guide/api/PlanFragment.md +47 -0
- chronaxis/guide/api/PlanValidationError.md +98 -0
- chronaxis/guide/api/PresetSpec.md +63 -0
- chronaxis/guide/api/ResultClosedError.md +14 -0
- chronaxis/guide/api/RunMetadata.md +100 -0
- chronaxis/guide/api/TimeConversion.md +29 -0
- chronaxis/guide/api/TimeOverflowError.md +17 -0
- chronaxis/guide/api/build_preset.md +36 -0
- chronaxis/guide/api/checked_add_ns.md +30 -0
- chronaxis/guide/api/convert_time.md +40 -0
- chronaxis/guide/api/explain_analysis_plan.md +38 -0
- chronaxis/guide/api/index.json +185 -0
- chronaxis/guide/api/load_analysis_plan.md +34 -0
- chronaxis/guide/api/load_batch_plan.md +36 -0
- chronaxis/guide/api/parse_datetime_ns.md +35 -0
- chronaxis/guide/api/parse_duration.md +30 -0
- chronaxis/guide/api/resolve_preset_roles.md +37 -0
- chronaxis/guide/api/run_batch.md +38 -0
- chronaxis/guide/api/shift_times_reference.md +33 -0
- chronaxis/guide/api/time_deltas_reference.md +37 -0
- chronaxis/guide/api/validate_analysis_plan.md +38 -0
- chronaxis/guide/en/README.md +74 -0
- chronaxis/guide/en/api/AnalysisError.md +14 -0
- chronaxis/guide/en/api/AnalysisPlan.md +93 -0
- chronaxis/guide/en/api/AnalysisResult.md +398 -0
- chronaxis/guide/en/api/AnalysisRunner.md +191 -0
- chronaxis/guide/en/api/BatchJob.md +17 -0
- chronaxis/guide/en/api/BatchJobResult.md +43 -0
- chronaxis/guide/en/api/BatchPlan.md +37 -0
- chronaxis/guide/en/api/BatchReport.md +52 -0
- chronaxis/guide/en/api/BatchRunner.md +51 -0
- chronaxis/guide/en/api/OutputManifest.md +23 -0
- chronaxis/guide/en/api/PlanFragment.md +33 -0
- chronaxis/guide/en/api/PlanValidationError.md +58 -0
- chronaxis/guide/en/api/PresetSpec.md +51 -0
- chronaxis/guide/en/api/ResultClosedError.md +14 -0
- chronaxis/guide/en/api/RunMetadata.md +100 -0
- chronaxis/guide/en/api/TimeConversion.md +23 -0
- chronaxis/guide/en/api/TimeOverflowError.md +14 -0
- chronaxis/guide/en/api/build_preset.md +23 -0
- chronaxis/guide/en/api/checked_add_ns.md +21 -0
- chronaxis/guide/en/api/convert_time.md +25 -0
- chronaxis/guide/en/api/explain_analysis_plan.md +30 -0
- chronaxis/guide/en/api/index.json +185 -0
- chronaxis/guide/en/api/load_analysis_plan.md +27 -0
- chronaxis/guide/en/api/load_batch_plan.md +28 -0
- chronaxis/guide/en/api/parse_datetime_ns.md +23 -0
- chronaxis/guide/en/api/parse_duration.md +20 -0
- chronaxis/guide/en/api/resolve_preset_roles.md +23 -0
- chronaxis/guide/en/api/run_batch.md +39 -0
- chronaxis/guide/en/api/shift_times_reference.md +21 -0
- chronaxis/guide/en/api/time_deltas_reference.md +22 -0
- chronaxis/guide/en/api/validate_analysis_plan.md +29 -0
- chronaxis/guide/en/fields/analysis/calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/calculations-all-2.json +300 -0
- chronaxis/guide/en/fields/analysis/calculations-all-3.json +84 -0
- chronaxis/guide/en/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/en/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/en/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/en/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/en/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/en/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-1.json +345 -0
- chronaxis/guide/en/fields/analysis/message_calculations-all-2.json +270 -0
- chronaxis/guide/en/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/en/fields/analysis/outputs-all-1.json +332 -0
- chronaxis/guide/en/fields/analysis/outputs-all-2.json +319 -0
- chronaxis/guide/en/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/en/fields/analysis/outputs-all-4.json +236 -0
- chronaxis/guide/en/fields/analysis/outputs-all-5.json +246 -0
- chronaxis/guide/en/fields/analysis/outputs-all-6.json +214 -0
- chronaxis/guide/en/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/en/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/en/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/en/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/en/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/en/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/en/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/en/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-1.json +333 -0
- chronaxis/guide/en/fields/analysis/rules-start_end-2.json +60 -0
- chronaxis/guide/en/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-1.json +338 -0
- chronaxis/guide/en/fields/analysis/rules-window_delta-2.json +96 -0
- chronaxis/guide/en/fields/analysis/sequences-all-1.json +378 -0
- chronaxis/guide/en/fields/analysis/sequences-all-2.json +70 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-3.json +323 -0
- chronaxis/guide/en/fields/analysis/signals-variant-1-4.json +192 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-2.json +312 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-3.json +294 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-4.json +253 -0
- chronaxis/guide/en/fields/analysis/signals-variant-2-5.json +44 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/en/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/en/fields/analysis/sources-memory-1.json +332 -0
- chronaxis/guide/en/fields/analysis/sources-memory-2.json +125 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/en/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-signal_csv-3.json +315 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-2.json +307 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-3.json +312 -0
- chronaxis/guide/en/fields/analysis/sources-variant-6-4.json +113 -0
- chronaxis/guide/en/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/en/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/en/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/en/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/en/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/en/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/en/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/en/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/en/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/en/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/en/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/en/fields/definitions/signals-all-3.json +290 -0
- chronaxis/guide/en/fields/definitions/signals-all-4.json +347 -0
- chronaxis/guide/en/fields/definitions/signals-all-5.json +297 -0
- chronaxis/guide/en/fields/definitions/signals-all-6.json +259 -0
- chronaxis/guide/en/fields/definitions/signals-all-7.json +117 -0
- chronaxis/guide/en/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/en/fields/definitions/sources-all-10.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-11.json +294 -0
- chronaxis/guide/en/fields/definitions/sources-all-12.json +212 -0
- chronaxis/guide/en/fields/definitions/sources-all-13.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-15.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-16.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-18.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-19.json +213 -0
- chronaxis/guide/en/fields/definitions/sources-all-2.json +323 -0
- chronaxis/guide/en/fields/definitions/sources-all-20.json +217 -0
- chronaxis/guide/en/fields/definitions/sources-all-21.json +210 -0
- chronaxis/guide/en/fields/definitions/sources-all-22.json +214 -0
- chronaxis/guide/en/fields/definitions/sources-all-23.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-24.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-25.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-26.json +218 -0
- chronaxis/guide/en/fields/definitions/sources-all-27.json +224 -0
- chronaxis/guide/en/fields/definitions/sources-all-28.json +215 -0
- chronaxis/guide/en/fields/definitions/sources-all-29.json +205 -0
- chronaxis/guide/en/fields/definitions/sources-all-3.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-30.json +298 -0
- chronaxis/guide/en/fields/definitions/sources-all-31.json +315 -0
- chronaxis/guide/en/fields/definitions/sources-all-32.json +306 -0
- chronaxis/guide/en/fields/definitions/sources-all-33.json +209 -0
- chronaxis/guide/en/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/en/fields/definitions/sources-all-5.json +299 -0
- chronaxis/guide/en/fields/definitions/sources-all-6.json +307 -0
- chronaxis/guide/en/fields/definitions/sources-all-7.json +320 -0
- chronaxis/guide/en/fields/definitions/sources-all-8.json +303 -0
- chronaxis/guide/en/fields/definitions/sources-all-9.json +315 -0
- chronaxis/guide/en/fields/index.json +3450 -0
- chronaxis/guide/en/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/en/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/en/fields/mapping/analysis-all-10.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-11.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-12.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-13.json +314 -0
- chronaxis/guide/en/fields/mapping/analysis-all-14.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-15.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-16.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-18.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-19.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-2.json +323 -0
- chronaxis/guide/en/fields/mapping/analysis-all-20.json +221 -0
- chronaxis/guide/en/fields/mapping/analysis-all-21.json +237 -0
- chronaxis/guide/en/fields/mapping/analysis-all-22.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-23.json +222 -0
- chronaxis/guide/en/fields/mapping/analysis-all-24.json +231 -0
- chronaxis/guide/en/fields/mapping/analysis-all-25.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-27.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-28.json +230 -0
- chronaxis/guide/en/fields/mapping/analysis-all-29.json +223 -0
- chronaxis/guide/en/fields/mapping/analysis-all-3.json +318 -0
- chronaxis/guide/en/fields/mapping/analysis-all-30.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-31.json +218 -0
- chronaxis/guide/en/fields/mapping/analysis-all-32.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-33.json +233 -0
- chronaxis/guide/en/fields/mapping/analysis-all-34.json +225 -0
- chronaxis/guide/en/fields/mapping/analysis-all-35.json +228 -0
- chronaxis/guide/en/fields/mapping/analysis-all-36.json +226 -0
- chronaxis/guide/en/fields/mapping/analysis-all-37.json +244 -0
- chronaxis/guide/en/fields/mapping/analysis-all-38.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-39.json +299 -0
- chronaxis/guide/en/fields/mapping/analysis-all-4.json +297 -0
- chronaxis/guide/en/fields/mapping/analysis-all-40.json +311 -0
- chronaxis/guide/en/fields/mapping/analysis-all-41.json +310 -0
- chronaxis/guide/en/fields/mapping/analysis-all-42.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-43.json +267 -0
- chronaxis/guide/en/fields/mapping/analysis-all-44.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-45.json +279 -0
- chronaxis/guide/en/fields/mapping/analysis-all-46.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-47.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-48.json +294 -0
- chronaxis/guide/en/fields/mapping/analysis-all-49.json +253 -0
- chronaxis/guide/en/fields/mapping/analysis-all-5.json +312 -0
- chronaxis/guide/en/fields/mapping/analysis-all-50.json +346 -0
- chronaxis/guide/en/fields/mapping/analysis-all-51.json +324 -0
- chronaxis/guide/en/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/en/fields/mapping/analysis-all-53.json +317 -0
- chronaxis/guide/en/fields/mapping/analysis-all-54.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-55.json +302 -0
- chronaxis/guide/en/fields/mapping/analysis-all-56.json +319 -0
- chronaxis/guide/en/fields/mapping/analysis-all-57.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/en/fields/mapping/analysis-all-59.json +359 -0
- chronaxis/guide/en/fields/mapping/analysis-all-6.json +327 -0
- chronaxis/guide/en/fields/mapping/analysis-all-60.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-61.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-62.json +301 -0
- chronaxis/guide/en/fields/mapping/analysis-all-63.json +326 -0
- chronaxis/guide/en/fields/mapping/analysis-all-64.json +367 -0
- chronaxis/guide/en/fields/mapping/analysis-all-65.json +334 -0
- chronaxis/guide/en/fields/mapping/analysis-all-66.json +358 -0
- chronaxis/guide/en/fields/mapping/analysis-all-67.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-68.json +331 -0
- chronaxis/guide/en/fields/mapping/analysis-all-69.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-7.json +303 -0
- chronaxis/guide/en/fields/mapping/analysis-all-70.json +349 -0
- chronaxis/guide/en/fields/mapping/analysis-all-71.json +288 -0
- chronaxis/guide/en/fields/mapping/analysis-all-72.json +316 -0
- chronaxis/guide/en/fields/mapping/analysis-all-73.json +266 -0
- chronaxis/guide/en/fields/mapping/analysis-all-74.json +227 -0
- chronaxis/guide/en/fields/mapping/analysis-all-75.json +239 -0
- chronaxis/guide/en/fields/mapping/analysis-all-76.json +274 -0
- chronaxis/guide/en/fields/mapping/analysis-all-77.json +380 -0
- chronaxis/guide/en/fields/mapping/analysis-all-78.json +313 -0
- chronaxis/guide/en/fields/mapping/analysis-all-79.json +338 -0
- chronaxis/guide/en/fields/mapping/analysis-all-8.json +292 -0
- chronaxis/guide/en/fields/mapping/analysis-all-80.json +304 -0
- chronaxis/guide/en/fields/mapping/analysis-all-81.json +140 -0
- chronaxis/guide/en/fields/mapping/analysis-all-9.json +332 -0
- chronaxis/guide/en/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/en/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/en/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/en/semantics.md +70 -0
- chronaxis/guide/en/tasks.json +290 -0
- chronaxis/guide/en/workflow.md +41 -0
- chronaxis/guide/examples/analysis-imports.yaml +22 -0
- chronaxis/guide/examples/analysis.yaml +23 -0
- chronaxis/guide/examples/batch-minimal.yaml +3 -0
- chronaxis/guide/examples/conditional-energy.yaml +36 -0
- chronaxis/guide/examples/data/activity.csv +6 -0
- chronaxis/guide/examples/data/can/activity.asc +11 -0
- chronaxis/guide/examples/data/can/calculation-minimal.asc +6 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-1.asc +92 -0
- chronaxis/guide/examples/data/can/conditional-energy/part-2.asc +36 -0
- chronaxis/guide/examples/data/can/conditional-energy/signals.dbc +10 -0
- chronaxis/guide/examples/data/can/execution-comparison.asc +12 -0
- chronaxis/guide/examples/data/can/execution-report.asc +4 -0
- chronaxis/guide/examples/data/can/expression-extended.asc +11 -0
- chronaxis/guide/examples/data/can/interval-actual.asc +6 -0
- chronaxis/guide/examples/data/can/preset-charge-energy.asc +15 -0
- chronaxis/guide/examples/data/can/preset-charge-minimal.asc +11 -0
- chronaxis/guide/examples/data/can/preset-command-automatic.asc +11 -0
- chronaxis/guide/examples/data/can/preset-fault-context.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-delay.asc +7 -0
- chronaxis/guide/examples/data/can/preset-threshold-partial.asc +7 -0
- chronaxis/guide/examples/data/can/quality.asc +6 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part1.asc +4 -0
- chronaxis/guide/examples/data/can/quickstart-parts/part2.asc +3 -0
- chronaxis/guide/examples/data/can/quickstart.asc +6 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-condition_duration-minimal.asc +19 -0
- chronaxis/guide/examples/data/can/rule-debounce-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-falling_edge-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-hysteresis-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-start_end-extended.asc +35 -0
- chronaxis/guide/examples/data/can/rule-start_only-extended.asc +19 -0
- chronaxis/guide/examples/data/can/rule-window_delta-extended.asc +19 -0
- chronaxis/guide/examples/data/can/sequence-outcomes.asc +19 -0
- chronaxis/guide/examples/data/can/signal-types.asc +13 -0
- chronaxis/guide/examples/data/can/start-end.asc +30 -0
- chronaxis/guide/examples/data/can/teaching-base.asc +58 -0
- chronaxis/guide/examples/data/can/teaching.dbc +53 -0
- chronaxis/guide/examples/data/joint-current.csv +5 -0
- chronaxis/guide/examples/data/joint.asc +5 -0
- chronaxis/guide/examples/data/joint.dbc +7 -0
- chronaxis/guide/examples/data/message-clean.asc +6 -0
- chronaxis/guide/examples/data/message-direction.asc +7 -0
- chronaxis/guide/examples/data/message-direction.dbc +7 -0
- chronaxis/guide/examples/data/power.blf +0 -0
- chronaxis/guide/examples/data/power.dbc +6 -0
- chronaxis/guide/examples/data/quality.csv +5 -0
- chronaxis/guide/examples/data/raw-can-example.csv +5 -0
- chronaxis/guide/examples/data/signal-types.csv +5 -0
- chronaxis/guide/examples/data/signals.csv +6 -0
- chronaxis/guide/examples/data/timing.asc +6 -0
- chronaxis/guide/examples/data/timing.dbc +11 -0
- chronaxis/guide/examples/export-can-minimal.yaml +24 -0
- chronaxis/guide/examples/input-csv-minimal.yaml +23 -0
- chronaxis/guide/examples/preset-charge-energy.yaml +41 -0
- chronaxis/guide/examples/preset-charge-minimal.yaml +31 -0
- chronaxis/guide/examples/preset-fault-context.yaml +27 -0
- chronaxis/guide/examples/quality.yaml +19 -0
- chronaxis/guide/examples/sequence-outcomes.yaml +39 -0
- chronaxis/guide/examples/shared/definitions.yaml +14 -0
- chronaxis/guide/examples/signal-enum-minimal.yaml +19 -0
- chronaxis/guide/examples/signal-number-conversion.yaml +24 -0
- chronaxis/guide/examples/window-merged.yaml +28 -0
- chronaxis/guide/fields/analysis/calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/calculations-all-2.json +299 -0
- chronaxis/guide/fields/analysis/calculations-all-3.json +70 -0
- chronaxis/guide/fields/analysis/config_version-all-1.json +24 -0
- chronaxis/guide/fields/analysis/dataset-all-1.json +344 -0
- chronaxis/guide/fields/analysis/derived-all-1.json +147 -0
- chronaxis/guide/fields/analysis/diagnostics-all-1.json +69 -0
- chronaxis/guide/fields/analysis/execution-all-1.json +167 -0
- chronaxis/guide/fields/analysis/imports-all-1.json +39 -0
- chronaxis/guide/fields/analysis/intervals-all-1.json +173 -0
- chronaxis/guide/fields/analysis/message_calculations-all-1.json +360 -0
- chronaxis/guide/fields/analysis/message_calculations-all-2.json +255 -0
- chronaxis/guide/fields/analysis/metadata-all-1.json +24 -0
- chronaxis/guide/fields/analysis/outputs-all-1.json +349 -0
- chronaxis/guide/fields/analysis/outputs-all-2.json +302 -0
- chronaxis/guide/fields/analysis/outputs-all-3.json +321 -0
- chronaxis/guide/fields/analysis/outputs-all-4.json +253 -0
- chronaxis/guide/fields/analysis/outputs-all-5.json +244 -0
- chronaxis/guide/fields/analysis/outputs-all-6.json +199 -0
- chronaxis/guide/fields/analysis/overrides-all-1.json +104 -0
- chronaxis/guide/fields/analysis/presets-charge_session-1.json +398 -0
- chronaxis/guide/fields/analysis/presets-charge_session-2.json +114 -0
- chronaxis/guide/fields/analysis/presets-command_response-1.json +376 -0
- chronaxis/guide/fields/analysis/presets-fault_context-1.json +285 -0
- chronaxis/guide/fields/analysis/presets-threshold_excursion-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-1.json +344 -0
- chronaxis/guide/fields/analysis/rules-condition_duration-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-debounce-1.json +335 -0
- chronaxis/guide/fields/analysis/rules-falling_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-hysteresis-2.json +27 -0
- chronaxis/guide/fields/analysis/rules-rising_edge-1.json +317 -0
- chronaxis/guide/fields/analysis/rules-start_end-1.json +349 -0
- chronaxis/guide/fields/analysis/rules-start_end-2.json +44 -0
- chronaxis/guide/fields/analysis/rules-start_only-1.json +334 -0
- chronaxis/guide/fields/analysis/rules-window_delta-1.json +356 -0
- chronaxis/guide/fields/analysis/rules-window_delta-2.json +78 -0
- chronaxis/guide/fields/analysis/sequences-all-1.json +394 -0
- chronaxis/guide/fields/analysis/sequences-all-2.json +54 -0
- chronaxis/guide/fields/analysis/signals-variant-1-1.json +349 -0
- chronaxis/guide/fields/analysis/signals-variant-1-2.json +297 -0
- chronaxis/guide/fields/analysis/signals-variant-1-3.json +340 -0
- chronaxis/guide/fields/analysis/signals-variant-1-4.json +175 -0
- chronaxis/guide/fields/analysis/signals-variant-2-1.json +327 -0
- chronaxis/guide/fields/analysis/signals-variant-2-2.json +335 -0
- chronaxis/guide/fields/analysis/signals-variant-2-3.json +289 -0
- chronaxis/guide/fields/analysis/signals-variant-2-4.json +270 -0
- chronaxis/guide/fields/analysis/sources-can_asc-1.json +318 -0
- chronaxis/guide/fields/analysis/sources-can_asc-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_asc-3.json +311 -0
- chronaxis/guide/fields/analysis/sources-can_asc-4.json +69 -0
- chronaxis/guide/fields/analysis/sources-can_blf-1.json +317 -0
- chronaxis/guide/fields/analysis/sources-can_blf-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-can_blf-3.json +317 -0
- chronaxis/guide/fields/analysis/sources-memory-1.json +347 -0
- chronaxis/guide/fields/analysis/sources-memory-2.json +110 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-1.json +330 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-10.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-11.json +225 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-12.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-13.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-14.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-15.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-16.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-17.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-18.json +239 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-19.json +233 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-2.json +310 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-20.json +242 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-21.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-22.json +228 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-23.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-24.json +223 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-25.json +290 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-26.json +131 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-3.json +297 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-4.json +226 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-5.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-6.json +227 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-7.json +230 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-8.json +238 -0
- chronaxis/guide/fields/analysis/sources-raw_can_csv-9.json +239 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-1.json +331 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-signal_csv-3.json +295 -0
- chronaxis/guide/fields/analysis/sources-variant-6-1.json +319 -0
- chronaxis/guide/fields/analysis/sources-variant-6-2.json +327 -0
- chronaxis/guide/fields/analysis/sources-variant-6-3.json +314 -0
- chronaxis/guide/fields/analysis/sources-variant-6-4.json +91 -0
- chronaxis/guide/fields/analysis/windows-all-1.json +361 -0
- chronaxis/guide/fields/analysis/windows-all-2.json +187 -0
- chronaxis/guide/fields/batch/backend-all-1.json +26 -0
- chronaxis/guide/fields/batch/batch_version-all-1.json +22 -0
- chronaxis/guide/fields/batch/fail_fast-all-1.json +22 -0
- chronaxis/guide/fields/batch/inputs-all-1.json +161 -0
- chronaxis/guide/fields/batch/jobs-all-1.json +58 -0
- chronaxis/guide/fields/batch/process_count-all-1.json +23 -0
- chronaxis/guide/fields/batch/source-all-1.json +22 -0
- chronaxis/guide/fields/batch/template-all-1.json +22 -0
- chronaxis/guide/fields/definitions/derived-all-1.json +121 -0
- chronaxis/guide/fields/definitions/signals-all-1.json +336 -0
- chronaxis/guide/fields/definitions/signals-all-2.json +307 -0
- chronaxis/guide/fields/definitions/signals-all-3.json +305 -0
- chronaxis/guide/fields/definitions/signals-all-4.json +352 -0
- chronaxis/guide/fields/definitions/signals-all-5.json +311 -0
- chronaxis/guide/fields/definitions/signals-all-6.json +254 -0
- chronaxis/guide/fields/definitions/signals-all-7.json +88 -0
- chronaxis/guide/fields/definitions/sources-all-1.json +332 -0
- chronaxis/guide/fields/definitions/sources-all-10.json +307 -0
- chronaxis/guide/fields/definitions/sources-all-11.json +280 -0
- chronaxis/guide/fields/definitions/sources-all-12.json +209 -0
- chronaxis/guide/fields/definitions/sources-all-13.json +219 -0
- chronaxis/guide/fields/definitions/sources-all-14.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-15.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-16.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-17.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-18.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-19.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-2.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-20.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-21.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-22.json +232 -0
- chronaxis/guide/fields/definitions/sources-all-23.json +213 -0
- chronaxis/guide/fields/definitions/sources-all-24.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-25.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-26.json +228 -0
- chronaxis/guide/fields/definitions/sources-all-27.json +212 -0
- chronaxis/guide/fields/definitions/sources-all-28.json +217 -0
- chronaxis/guide/fields/definitions/sources-all-29.json +227 -0
- chronaxis/guide/fields/definitions/sources-all-3.json +306 -0
- chronaxis/guide/fields/definitions/sources-all-30.json +333 -0
- chronaxis/guide/fields/definitions/sources-all-31.json +302 -0
- chronaxis/guide/fields/definitions/sources-all-32.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-33.json +89 -0
- chronaxis/guide/fields/definitions/sources-all-4.json +336 -0
- chronaxis/guide/fields/definitions/sources-all-5.json +313 -0
- chronaxis/guide/fields/definitions/sources-all-6.json +292 -0
- chronaxis/guide/fields/definitions/sources-all-7.json +319 -0
- chronaxis/guide/fields/definitions/sources-all-8.json +315 -0
- chronaxis/guide/fields/definitions/sources-all-9.json +318 -0
- chronaxis/guide/fields/index.json +3432 -0
- chronaxis/guide/fields/mapping/aliases-all-1.json +91 -0
- chronaxis/guide/fields/mapping/analysis-all-1.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-10.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-11.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-12.json +329 -0
- chronaxis/guide/fields/mapping/analysis-all-13.json +294 -0
- chronaxis/guide/fields/mapping/analysis-all-14.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-15.json +280 -0
- chronaxis/guide/fields/mapping/analysis-all-16.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-17.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-18.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-19.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-2.json +342 -0
- chronaxis/guide/fields/mapping/analysis-all-20.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-21.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-22.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-23.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-24.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-25.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-26.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-27.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-28.json +237 -0
- chronaxis/guide/fields/mapping/analysis-all-29.json +233 -0
- chronaxis/guide/fields/mapping/analysis-all-3.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-30.json +244 -0
- chronaxis/guide/fields/mapping/analysis-all-31.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-32.json +226 -0
- chronaxis/guide/fields/mapping/analysis-all-33.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-34.json +227 -0
- chronaxis/guide/fields/mapping/analysis-all-35.json +230 -0
- chronaxis/guide/fields/mapping/analysis-all-36.json +221 -0
- chronaxis/guide/fields/mapping/analysis-all-37.json +291 -0
- chronaxis/guide/fields/mapping/analysis-all-38.json +315 -0
- chronaxis/guide/fields/mapping/analysis-all-39.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-4.json +312 -0
- chronaxis/guide/fields/mapping/analysis-all-40.json +307 -0
- chronaxis/guide/fields/mapping/analysis-all-41.json +292 -0
- chronaxis/guide/fields/mapping/analysis-all-42.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-43.json +296 -0
- chronaxis/guide/fields/mapping/analysis-all-44.json +322 -0
- chronaxis/guide/fields/mapping/analysis-all-45.json +298 -0
- chronaxis/guide/fields/mapping/analysis-all-46.json +347 -0
- chronaxis/guide/fields/mapping/analysis-all-47.json +302 -0
- chronaxis/guide/fields/mapping/analysis-all-48.json +263 -0
- chronaxis/guide/fields/mapping/analysis-all-49.json +301 -0
- chronaxis/guide/fields/mapping/analysis-all-5.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-50.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-51.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-52.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-53.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-54.json +339 -0
- chronaxis/guide/fields/mapping/analysis-all-55.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-56.json +336 -0
- chronaxis/guide/fields/mapping/analysis-all-57.json +335 -0
- chronaxis/guide/fields/mapping/analysis-all-58.json +333 -0
- chronaxis/guide/fields/mapping/analysis-all-59.json +325 -0
- chronaxis/guide/fields/mapping/analysis-all-6.json +323 -0
- chronaxis/guide/fields/mapping/analysis-all-60.json +334 -0
- chronaxis/guide/fields/mapping/analysis-all-61.json +311 -0
- chronaxis/guide/fields/mapping/analysis-all-62.json +289 -0
- chronaxis/guide/fields/mapping/analysis-all-63.json +383 -0
- chronaxis/guide/fields/mapping/analysis-all-64.json +357 -0
- chronaxis/guide/fields/mapping/analysis-all-65.json +375 -0
- chronaxis/guide/fields/mapping/analysis-all-66.json +351 -0
- chronaxis/guide/fields/mapping/analysis-all-67.json +346 -0
- chronaxis/guide/fields/mapping/analysis-all-68.json +317 -0
- chronaxis/guide/fields/mapping/analysis-all-69.json +313 -0
- chronaxis/guide/fields/mapping/analysis-all-7.json +306 -0
- chronaxis/guide/fields/mapping/analysis-all-70.json +326 -0
- chronaxis/guide/fields/mapping/analysis-all-71.json +316 -0
- chronaxis/guide/fields/mapping/analysis-all-72.json +264 -0
- chronaxis/guide/fields/mapping/analysis-all-73.json +228 -0
- chronaxis/guide/fields/mapping/analysis-all-74.json +241 -0
- chronaxis/guide/fields/mapping/analysis-all-75.json +273 -0
- chronaxis/guide/fields/mapping/analysis-all-76.json +382 -0
- chronaxis/guide/fields/mapping/analysis-all-77.json +328 -0
- chronaxis/guide/fields/mapping/analysis-all-78.json +338 -0
- chronaxis/guide/fields/mapping/analysis-all-79.json +304 -0
- chronaxis/guide/fields/mapping/analysis-all-8.json +309 -0
- chronaxis/guide/fields/mapping/analysis-all-80.json +140 -0
- chronaxis/guide/fields/mapping/analysis-all-9.json +329 -0
- chronaxis/guide/fields/mapping/io_policy-all-1.json +19 -0
- chronaxis/guide/fields/mapping/mapping_version-all-1.json +19 -0
- chronaxis/guide/fields/mapping/path_base-all-1.json +19 -0
- chronaxis/guide/fields/mapping/sections-all-1.json +402 -0
- chronaxis/guide/fields/mapping/sections-all-2.json +232 -0
- chronaxis/guide/lookup.py +90 -0
- chronaxis/guide/manifest.json +614 -0
- chronaxis/guide/run_analysis.py +34 -0
- chronaxis/guide/schemas/analysis.schema.json +8451 -0
- chronaxis/guide/schemas/batch-v1.schema.json +172 -0
- chronaxis/guide/schemas/definitions.schema.json +29 -0
- chronaxis/guide/schemas/legacy-import-v1.schema.json +143 -0
- chronaxis/guide/semantics.md +62 -0
- chronaxis/guide/tasks.json +290 -0
- chronaxis/guide/workflow.md +38 -0
- chronaxis/legacy/__init__.py +46 -0
- chronaxis/legacy/batch_read.py +412 -0
- chronaxis/legacy/batch_validation.py +134 -0
- chronaxis/legacy/batch_wire.py +264 -0
- chronaxis/legacy/batch_worker.py +417 -0
- chronaxis/legacy/binding.py +154 -0
- chronaxis/legacy/dbc_cycles.py +47 -0
- chronaxis/legacy/decode_policy.py +28 -0
- chronaxis/legacy/disjunction.py +79 -0
- chronaxis/legacy/export_worker.py +147 -0
- chronaxis/legacy/export_write.py +378 -0
- chronaxis/legacy/message_store.py +562 -0
- chronaxis/legacy/process_read.py +526 -0
- chronaxis/legacy/raw_store.py +341 -0
- chronaxis/legacy/records.py +709 -0
- chronaxis/legacy/required_records.py +122 -0
- chronaxis/legacy/sum.py +403 -0
- chronaxis/legacy/sum_numpy.py +43 -0
- chronaxis/legacy/updates.py +277 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/can_processor.py +138 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/file_processor.py +218 -0
- chronaxis/legacy/vendor/sclicer_functions_v1/utils.py +447 -0
- chronaxis/legacy/worker.py +352 -0
- chronaxis/migration/__init__.py +11 -0
- chronaxis/migration/api.py +270 -0
- chronaxis/migration/ini.py +110 -0
- chronaxis/migration/legacy_sum.py +304 -0
- chronaxis/migration/models.py +83 -0
- chronaxis/migration/publication.py +230 -0
- chronaxis/migration/sclicer.py +241 -0
- chronaxis/migration/slope.py +78 -0
- chronaxis/migration/start_end.py +48 -0
- chronaxis/planning/__init__.py +19 -0
- chronaxis/planning/channels.py +30 -0
- chronaxis/planning/checks.py +447 -0
- chronaxis/planning/config_groups.py +215 -0
- chronaxis/planning/dbc_defaults.py +88 -0
- chronaxis/planning/export_options.py +247 -0
- chronaxis/planning/input_defaults.py +62 -0
- chronaxis/planning/input_paths.py +124 -0
- chronaxis/planning/input_requirements.py +250 -0
- chronaxis/planning/inputs.py +306 -0
- chronaxis/planning/intervals.py +242 -0
- chronaxis/planning/legacy_execution.py +38 -0
- chronaxis/planning/message_calculations.py +171 -0
- chronaxis/planning/models.py +369 -0
- chronaxis/planning/nodes.py +355 -0
- chronaxis/planning/plan.py +294 -0
- chronaxis/planning/preset_models.py +211 -0
- chronaxis/planning/record_execution.py +76 -0
- chronaxis/planning/reports.py +523 -0
- chronaxis/planning/sequences.py +91 -0
- chronaxis/planning/signal_groups.py +61 -0
- chronaxis/planning/signal_validity.py +46 -0
- chronaxis/planning/text_inputs.py +110 -0
- chronaxis/presets.py +270 -0
- chronaxis/results/__init__.py +34 -0
- chronaxis/results/analysis_outcome.py +67 -0
- chronaxis/results/artifact_exports.py +212 -0
- chronaxis/results/binding_metadata.py +54 -0
- chronaxis/results/budget.py +138 -0
- chronaxis/results/can_metadata.py +247 -0
- chronaxis/results/codec.py +246 -0
- chronaxis/results/errors.py +25 -0
- chronaxis/results/export_files.py +216 -0
- chronaxis/results/frame_exports.py +299 -0
- chronaxis/results/frame_patch.py +186 -0
- chronaxis/results/frame_rebuild.py +458 -0
- chronaxis/results/frame_sort.py +223 -0
- chronaxis/results/input_diagnostics.py +51 -0
- chronaxis/results/manifest.py +343 -0
- chronaxis/results/merge_runs.py +207 -0
- chronaxis/results/owned_directory.py +32 -0
- chronaxis/results/raw_exports.py +689 -0
- chronaxis/results/readable.py +355 -0
- chronaxis/results/readable_format.py +94 -0
- chronaxis/results/result.py +734 -0
- chronaxis/results/rows.py +57 -0
- chronaxis/results/signal_exports.py +209 -0
- chronaxis/results/signal_grid.py +219 -0
- chronaxis/results/spool.py +421 -0
- chronaxis/results/summary.py +350 -0
- chronaxis/results/text_can_metadata.py +64 -0
- chronaxis/results/threshold_metadata.py +105 -0
- chronaxis/runner.py +121 -0
- chronaxis/sources/__init__.py +23 -0
- chronaxis/sources/asc.py +412 -0
- chronaxis/sources/blf.py +101 -0
- chronaxis/sources/can_spec.py +179 -0
- chronaxis/sources/can_updates.py +160 -0
- chronaxis/sources/csv_spec.py +133 -0
- chronaxis/sources/descriptions.py +65 -0
- chronaxis/sources/memory.py +299 -0
- chronaxis/sources/models.py +497 -0
- chronaxis/sources/packing.py +170 -0
- chronaxis/sources/protocol.py +221 -0
- chronaxis/sources/raw_can.py +62 -0
- chronaxis/sources/raw_csv.py +470 -0
- chronaxis/sources/raw_csv_layout.py +310 -0
- chronaxis/sources/signal_csv.py +608 -0
- chronaxis/sources/text_can_decode.py +421 -0
- chronaxis/sources/text_can_ref.py +48 -0
- chronaxis/sources/text_can_spec.py +61 -0
- chronaxis/timebase/__init__.py +19 -0
- chronaxis/timebase/conversion.py +364 -0
- chronaxis/timebase/numpy_ops.py +104 -0
- chronaxis/user_guide.py +81 -0
- chronaxis-0.1.0.dev0.dist-info/METADATA +172 -0
- chronaxis-0.1.0.dev0.dist-info/RECORD +917 -0
- chronaxis-0.1.0.dev0.dist-info/WHEEL +5 -0
- chronaxis-0.1.0.dev0.dist-info/entry_points.txt +2 -0
- chronaxis-0.1.0.dev0.dist-info/licenses/LICENSE +21 -0
- chronaxis-0.1.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
"""保存原始片段索引并复制已生成的BLF,不重新调用旧读写或解码路径。
|
|
2
|
+
|
|
3
|
+
输入是实际Segment范围、已关闭的BLF文件及其明确摘要,输出是连续编号的有界
|
|
4
|
+
JSONL索引和发布目录内的逐文件副本。exported保留正长actual,即使文件含零帧;
|
|
5
|
+
empty_range保留已知零长度actual;no_observation仅用于actual为None,不造空文件。
|
|
6
|
+
append核实际BLF字节/SHA后写索引;seal真正关闭writer才开放独立reader。reader只有
|
|
7
|
+
完整EOF、流SHA/数量与真实关闭均成功后才verified_eof,提前关闭不能证明完整。
|
|
8
|
+
|
|
9
|
+
所有新增RAM与索引spool先预约,原BLF由旧writer封装预约,本模块不重复计算。
|
|
10
|
+
copy_to只逐条读索引、有限块复制和核现成BLF;发布副本不计入分析暂存配额。
|
|
11
|
+
输出失败只清本次复制资源,保sealed输入与其他reader,恢复后可向新目录重试;
|
|
12
|
+
原索引或原BLF内容损坏仍使输入仓failed,不把坏输入当作可发布结果。
|
|
13
|
+
所有真实FD、未返回reader和费用槽由本store可达,关闭失败可重试,保原异常/取消
|
|
14
|
+
及最高raw_export_store_cleanup_owner;文件与累计spool保留,不凭共享余额补账。
|
|
15
|
+
本模块只依赖标准库、冻结模型和有界JSON,不导入CAN库,不声称整进程RSS受限。
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# 固定模型与有界编码不触及原日志/DBC;资源交易复用新结果层已经验证的协议。
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from hashlib import sha256
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from re import fullmatch
|
|
23
|
+
from ..core.models import Interval
|
|
24
|
+
from ..core.validation import require_identifier
|
|
25
|
+
from ..legacy.records import MAX_WIRE_BYTES, encode_packet, decode_packet
|
|
26
|
+
from ..timebase.conversion import INT64_MAX, require_int64_ns
|
|
27
|
+
from .budget import ResourceBudget
|
|
28
|
+
from .errors import ResultClosedError, ResultFormatError
|
|
29
|
+
from .spool import _cleanup_owner, _reserve_owned_ram, _release_owned_ram
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
_FIELDS = ('index', 'source', 'session_id', 'segment_id', 'window_id', 'requested',
|
|
33
|
+
'actual', 'frame_count', 'file_name', 'sha256', 'byte_count', 'status', 'device_label')
|
|
34
|
+
_ROW_COST = 65536 + 64 * MAX_WIRE_BYTES
|
|
35
|
+
_CHUNK_BYTES = 65536
|
|
36
|
+
_IO_COST = 8 * _CHUNK_BYTES
|
|
37
|
+
_MAX_INDEX = 999999999999
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _integer(value, name, maximum=INT64_MAX):
|
|
41
|
+
"""校验非负原生整数,不把bool或浮点作为数量。
|
|
42
|
+
|
|
43
|
+
参数: value候选;name错误位置;maximum含端点上限。返回: 原int。
|
|
44
|
+
异常: TypeError/ValueError为类型或范围错误;不截断、不转换。
|
|
45
|
+
"""
|
|
46
|
+
if type(value) is not int:
|
|
47
|
+
raise TypeError(name + '需要原生int')
|
|
48
|
+
if not 0 <= value <= maximum:
|
|
49
|
+
raise ValueError(name + '超出允许范围')
|
|
50
|
+
return value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _text(value, name, *, identifier=False):
|
|
54
|
+
"""检查有界安全原文本,保留大小写、Unicode和合法ID标点。
|
|
55
|
+
|
|
56
|
+
参数: value原文本;name位置;identifier要求来源/会话简单名。返回: 原str。
|
|
57
|
+
异常: TypeError/ValueError为非原生str、空白、控制字符、过长或名称非法。
|
|
58
|
+
"""
|
|
59
|
+
if type(value) is not str:
|
|
60
|
+
raise TypeError(name + '需要原生str')
|
|
61
|
+
if not value.strip() or len(value) > MAX_WIRE_BYTES or any(ord(char) < 32 or ord(char) == 127 for char in value):
|
|
62
|
+
raise ValueError(name + '为空、含控制字符或超过有界文本能力')
|
|
63
|
+
if identifier:
|
|
64
|
+
require_identifier(value, name)
|
|
65
|
+
return value
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _interval(value, name):
|
|
69
|
+
"""要求冻结Interval及原生int64端点,不重建或改变原范围。
|
|
70
|
+
|
|
71
|
+
参数: value范围;name位置。返回: 原Interval。
|
|
72
|
+
异常: TypeError/ValueError/OverflowError为类型、顺序或整数范围非法。
|
|
73
|
+
"""
|
|
74
|
+
if type(value) is not Interval:
|
|
75
|
+
raise TypeError(name + '需要Interval')
|
|
76
|
+
for endpoint in (value.start_ns, value.end_ns):
|
|
77
|
+
if type(endpoint) is not int:
|
|
78
|
+
raise TypeError(name + '端点需要原生int64')
|
|
79
|
+
require_int64_ns(endpoint, name)
|
|
80
|
+
require_int64_ns(value.end_ns - value.start_ns, name + '.duration')
|
|
81
|
+
if value.end_ns < value.start_ns:
|
|
82
|
+
raise ValueError(name + '不能反向')
|
|
83
|
+
return value
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _packet(record):
|
|
87
|
+
"""把固定模型转为固定JSON树,不复制文件内容或任意元数据。
|
|
88
|
+
|
|
89
|
+
参数: record为RawExportRecord。返回: 仅13字段dict。
|
|
90
|
+
异常: 内部模型属性错误传播;调用者另核整包64KiB上限。
|
|
91
|
+
"""
|
|
92
|
+
result = {name: getattr(record, name) for name in _FIELDS}
|
|
93
|
+
for name in ('requested', 'actual'):
|
|
94
|
+
interval = result[name]
|
|
95
|
+
result[name] = None if interval is None else dict(start_ns=interval.start_ns, end_ns=interval.end_ns)
|
|
96
|
+
return result
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@dataclass(frozen=True)
|
|
100
|
+
class RawExportRecord:
|
|
101
|
+
"""保存一个原片段导出事实;构造校声明,不据此宣称文件已读取或写出。"""
|
|
102
|
+
|
|
103
|
+
index: int # 从0连续;对应唯一12位文件名,非业务排序键。
|
|
104
|
+
source: str # 同一store的CAN来源安全名。
|
|
105
|
+
session_id: str # 原会话安全名。
|
|
106
|
+
segment_id: str # 实际Segment的原ID。
|
|
107
|
+
window_id: str # 产生原片段的窗口ID。
|
|
108
|
+
requested: Interval # 保留完整原请求范围。
|
|
109
|
+
actual: Interval | None # 原实际交集;已知点与无观测严格区分。
|
|
110
|
+
frame_count: int # 原writer成功交付的帧数;正长范围可为0。
|
|
111
|
+
file_name: str | None # exported固定为raw_segments/12位.blf。
|
|
112
|
+
sha256: str | None # 实际输出BLF字节SHA,不是原输入SHA。
|
|
113
|
+
byte_count: int # 实际输出文件字节数。
|
|
114
|
+
status: str # exported/empty_range/no_observation。
|
|
115
|
+
device_label: str # 本条产生设备标签,与store严格一致。
|
|
116
|
+
|
|
117
|
+
def __post_init__(self):
|
|
118
|
+
"""检查数量、身份、范围和文件状态的闭合关系,整条记录有界。
|
|
119
|
+
|
|
120
|
+
参数: 无,读取冻结字段。返回: None。
|
|
121
|
+
异常: TypeError/ValueError/OverflowError为非法事实;不打开、stat或创建文件。
|
|
122
|
+
"""
|
|
123
|
+
_integer(self.index, 'raw_export.index', _MAX_INDEX)
|
|
124
|
+
_integer(self.frame_count, 'raw_export.frame_count')
|
|
125
|
+
_integer(self.byte_count, 'raw_export.byte_count')
|
|
126
|
+
for name in ('source', 'session_id', 'segment_id', 'window_id', 'device_label'):
|
|
127
|
+
_text(getattr(self, name), name, identifier=name in ('source', 'session_id'))
|
|
128
|
+
_interval(self.requested, 'raw_export.requested')
|
|
129
|
+
if self.actual is not None:
|
|
130
|
+
_interval(self.actual, 'raw_export.actual')
|
|
131
|
+
if self.actual.start_ns < self.requested.start_ns or self.actual.end_ns > self.requested.end_ns:
|
|
132
|
+
raise ValueError('raw_export.actual必须落在原requested内')
|
|
133
|
+
if type(self.status) is not str or self.status not in ('exported', 'empty_range', 'no_observation'):
|
|
134
|
+
raise ValueError('原始导出状态非法')
|
|
135
|
+
if self.status == 'exported':
|
|
136
|
+
if self.actual is None or self.actual.start_ns == self.actual.end_ns:
|
|
137
|
+
raise ValueError('exported需正长实际范围')
|
|
138
|
+
if type(self.file_name) is not str or self.file_name != f'raw_segments/{self.index:012d}.blf':
|
|
139
|
+
raise ValueError('原始导出文件名必须对应当前连续索引')
|
|
140
|
+
if type(self.sha256) is not str or fullmatch(r'[0-9a-fA-F]{64}', self.sha256) is None:
|
|
141
|
+
raise ValueError('原始导出SHA需64位十六进制')
|
|
142
|
+
else:
|
|
143
|
+
expected = self.actual is None if self.status == 'no_observation' else self.actual is not None and self.actual.start_ns == self.actual.end_ns
|
|
144
|
+
if not expected or self.file_name is not None or self.sha256 is not None or self.frame_count or self.byte_count:
|
|
145
|
+
raise ValueError('无观测/零范围必须保原actual且不得带文件、SHA或帧字节数')
|
|
146
|
+
# 在模型边界按现有wire能力校整包,避免多个单独合法长文本拼成无界行。
|
|
147
|
+
if len(encode_packet(_packet(self))) + 1 > MAX_WIRE_BYTES:
|
|
148
|
+
raise ValueError('原始导出索引行超过64KiB')
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _decode(payload):
|
|
152
|
+
"""严格还原一条固定索引,不接受多键、重复JSON键或浮点端点。
|
|
153
|
+
|
|
154
|
+
参数: payload为不含换行的有限bytes。返回: RawExportRecord。
|
|
155
|
+
异常: ResultFormatError保留底层结构/类型/时间校验原因;取消原样传播。
|
|
156
|
+
"""
|
|
157
|
+
try:
|
|
158
|
+
value = decode_packet(payload)
|
|
159
|
+
if set(value) != set(_FIELDS):
|
|
160
|
+
raise ValueError('原始导出索引字段缺失或多余')
|
|
161
|
+
for name in ('requested', 'actual'):
|
|
162
|
+
interval = value[name]
|
|
163
|
+
if interval is None and name == 'actual':
|
|
164
|
+
continue
|
|
165
|
+
if type(interval) is not dict or set(interval) != {'start_ns', 'end_ns'}:
|
|
166
|
+
raise ValueError('索引范围必须精确含start_ns/end_ns')
|
|
167
|
+
if type(interval['start_ns']) is not int or type(interval['end_ns']) is not int:
|
|
168
|
+
raise TypeError('索引范围端点必须为原生int')
|
|
169
|
+
value[name] = Interval(interval['start_ns'], interval['end_ns'])
|
|
170
|
+
return RawExportRecord(**value)
|
|
171
|
+
except (TypeError, ValueError, OverflowError, UnicodeError) as exc:
|
|
172
|
+
raise ResultFormatError('原始导出索引行非法: ' + str(exc)) from exc
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _write_all(handle, payload):
|
|
176
|
+
"""完整写有限bytes,短写继续,零写或非法返回立即失败。
|
|
177
|
+
|
|
178
|
+
参数: handle真实无缓冲FD;payload有限bytes。返回: None。
|
|
179
|
+
异常: 原write/取消或OSError;费用由调用方先预约,不在此重复计算。
|
|
180
|
+
"""
|
|
181
|
+
view = memoryview(payload)
|
|
182
|
+
while view:
|
|
183
|
+
written = handle.write(view)
|
|
184
|
+
if type(written) is not int or not 0 < written <= len(view):
|
|
185
|
+
raise OSError('原始导出文件写入未正确推进')
|
|
186
|
+
view = view[written:]
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class RawExportStore:
|
|
190
|
+
"""拥有索引、活reader与当前复制FD;状态与真实closed事实分别记录。
|
|
191
|
+
|
|
192
|
+
building只可append/seal;sealed可独立回读或重复copy。构建或输入完整性失败
|
|
193
|
+
转failed;普通复制输出失败仅恢复本次资源。关闭中只允许重试close,不丢槽。
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
format = 'blf'
|
|
197
|
+
|
|
198
|
+
def __init__(self, budget, work_dir, source, session_id, device_label='pending'):
|
|
199
|
+
"""先付固定费用,再在全新根独占创建目录和索引writer。
|
|
200
|
+
|
|
201
|
+
参数: budget为借用ResourceBudget;work_dir为全新str/Path;source/session_id
|
|
202
|
+
为安全名;device_label为有界原标签,默认pending。
|
|
203
|
+
返回: building仓。异常: 原声明/路径/预算/IO/取消;持续清理失败附最高恢复owner。
|
|
204
|
+
"""
|
|
205
|
+
if not isinstance(budget, ResourceBudget) or not isinstance(work_dir, (str, Path)):
|
|
206
|
+
raise TypeError('原始导出仓需ResourceBudget及显式新目录')
|
|
207
|
+
_text(source, 'raw_exports.source', identifier=True)
|
|
208
|
+
_text(session_id, 'raw_exports.session_id', identifier=True)
|
|
209
|
+
_text(device_label, 'raw_exports.device_label')
|
|
210
|
+
if sum(len(part) for part in Path(work_dir).parts) > MAX_WIRE_BYTES:
|
|
211
|
+
raise ValueError('原始导出工作路径超过有界能力')
|
|
212
|
+
self.budget = self._budget = budget
|
|
213
|
+
self.source, self.session_id, self.device_label = source, session_id, device_label
|
|
214
|
+
self.path = self.inventory_path = self._raw_path = None
|
|
215
|
+
self._writer = self._pending_reader = self._copy_reader = None
|
|
216
|
+
self._input_fd = self._output_fd = self._inventory_fd = None
|
|
217
|
+
self._readers = self._digest = self._payload = self._chunk = None
|
|
218
|
+
self._fixed_cost = self._append_cost = self._io_cost = self._copy_cost = self._held_cost = 0
|
|
219
|
+
self._spool_bytes = self.inventory_bytes = self.record_count = self.file_count = 0
|
|
220
|
+
self.sha256 = None
|
|
221
|
+
self.state, self._closed, self._closing = 'building', False, False
|
|
222
|
+
try:
|
|
223
|
+
# 路径/来源标签及活reader登记均有固定费用,首笔后取消也可从完整槽恢复。
|
|
224
|
+
requested = Path(work_dir)
|
|
225
|
+
_reserve_owned_ram(self, 65536 + 32 * (len(str(requested)) + len(source) + len(session_id) + len(device_label)), '_fixed_cost')
|
|
226
|
+
resolved = requested.resolve()
|
|
227
|
+
if any(part.casefold() == 'refprojects' for part in resolved.parts):
|
|
228
|
+
raise ValueError('原始导出仓禁止写入RefProjects')
|
|
229
|
+
resolved.mkdir(parents=True, exist_ok=False)
|
|
230
|
+
self.path, self._raw_path = resolved, resolved / 'raw_segments'
|
|
231
|
+
self._raw_path.mkdir(exist_ok=False)
|
|
232
|
+
self.inventory_path = resolved / 'raw_segments.jsonl'
|
|
233
|
+
self._readers, self._digest = set(), sha256()
|
|
234
|
+
self._writer = self.inventory_path.open('xb', buffering=0)
|
|
235
|
+
except BaseException as exc:
|
|
236
|
+
self._fail(exc)
|
|
237
|
+
raise
|
|
238
|
+
|
|
239
|
+
@property
|
|
240
|
+
def closed(self):
|
|
241
|
+
"""读取真实关闭事实。参数: 无。返回: bool。异常: 无,FD或费用未清不为True。"""
|
|
242
|
+
return self._closed
|
|
243
|
+
|
|
244
|
+
@property
|
|
245
|
+
def spool_bytes(self):
|
|
246
|
+
"""读取仅本索引新增的累计配额。参数: 无。返回: int。异常: 无,不含BLF或发布副本。"""
|
|
247
|
+
return self._spool_bytes
|
|
248
|
+
|
|
249
|
+
def _require(self, state):
|
|
250
|
+
"""检查活状态,半关闭或失败前缀不能继续使用。
|
|
251
|
+
|
|
252
|
+
参数: state为building/sealed。返回: None。异常: ResultClosedError/RuntimeError。
|
|
253
|
+
"""
|
|
254
|
+
if self._closed or self._closing:
|
|
255
|
+
raise ResultClosedError('原始导出仓已关闭或正在清理')
|
|
256
|
+
if self.state != state:
|
|
257
|
+
raise RuntimeError('原始导出仓状态不允许操作: ' + self.state)
|
|
258
|
+
|
|
259
|
+
def _fail(self, exc):
|
|
260
|
+
"""保原主错/取消、failed状态和最高恢复owner,清理副错只记note。
|
|
261
|
+
|
|
262
|
+
参数: exc为实际主异常。返回: None。异常: 清理错误不替代原exc。
|
|
263
|
+
"""
|
|
264
|
+
self.state = 'failed'
|
|
265
|
+
exc.raw_export_store_cleanup_owner = self
|
|
266
|
+
_cleanup_owner(self, exc, 'raw_export_store_cleanup_owner', '原始导出仓')
|
|
267
|
+
|
|
268
|
+
def next_path(self):
|
|
269
|
+
"""计算当前记录对应BLF路径,不创建文件、不跳过无观测索引。
|
|
270
|
+
|
|
271
|
+
参数: 无。返回: 根/raw_segments/{record_count:012d}.blf。
|
|
272
|
+
异常: 状态错误或索引超过12位能力;原writer由调用方独立持有和关闭。
|
|
273
|
+
"""
|
|
274
|
+
self._require('building')
|
|
275
|
+
_integer(self.record_count, 'raw_exports.record_count', _MAX_INDEX)
|
|
276
|
+
return self._raw_path / f'{self.record_count:012d}.blf'
|
|
277
|
+
|
|
278
|
+
def _relation(self, record, index):
|
|
279
|
+
"""核本仓归属和连续索引,不从文件名猜来源。
|
|
280
|
+
|
|
281
|
+
参数: record为冻结记录;index为当前预期号。返回: None。异常: TypeError/ValueError。
|
|
282
|
+
"""
|
|
283
|
+
if type(record) is not RawExportRecord:
|
|
284
|
+
raise TypeError('原始导出仓仅接受RawExportRecord')
|
|
285
|
+
if (record.index != index or record.source != self.source or record.session_id != self.session_id
|
|
286
|
+
or record.device_label != self.device_label):
|
|
287
|
+
raise ValueError('原始导出记录索引/来源/会话/设备不属于本仓')
|
|
288
|
+
|
|
289
|
+
def _close_fd(self, slot):
|
|
290
|
+
"""真实FD关闭后才撤槽,关闭后抛错也依据actual.closed处理。
|
|
291
|
+
|
|
292
|
+
参数: slot为本owner固定FD槽。返回: None。异常: 原close/取消,持续失败可重试。
|
|
293
|
+
"""
|
|
294
|
+
handle = getattr(self, slot)
|
|
295
|
+
if handle is not None:
|
|
296
|
+
try:
|
|
297
|
+
handle.close()
|
|
298
|
+
finally:
|
|
299
|
+
if handle.closed:
|
|
300
|
+
setattr(self, slot, None)
|
|
301
|
+
|
|
302
|
+
def _file(self, record, destination=None):
|
|
303
|
+
"""有限块核实际BLF;可同时复制到独占目标,不调用任何CAN读写器。
|
|
304
|
+
|
|
305
|
+
参数: record为exported记录;destination为None或新文件Path。返回: None。
|
|
306
|
+
异常: 原预算/IO/取消或ResultFormatError;所有当前FD仍从本store可达。
|
|
307
|
+
"""
|
|
308
|
+
if self._input_fd is not None or self._output_fd is not None or self._io_cost:
|
|
309
|
+
raise ResultClosedError('原始导出仓有未完成文件资源待清理')
|
|
310
|
+
_reserve_owned_ram(self, _IO_COST, '_io_cost')
|
|
311
|
+
try:
|
|
312
|
+
self._input_fd = (self.path / record.file_name).open('rb', buffering=0)
|
|
313
|
+
except FileNotFoundError as exc:
|
|
314
|
+
# 索引已指明存在的原件消失是输入失效;不能当成本次发布目录错误重试。
|
|
315
|
+
self._fail(exc)
|
|
316
|
+
raise
|
|
317
|
+
if destination is not None:
|
|
318
|
+
self._output_fd = destination.open('xb', buffering=0)
|
|
319
|
+
digest, count = sha256(), 0
|
|
320
|
+
# 原件和副本同时只持一个块;超过声明字节立即拒绝,不扫无界额外后缀。
|
|
321
|
+
while True:
|
|
322
|
+
self._chunk = self._input_fd.read(_CHUNK_BYTES)
|
|
323
|
+
if not self._chunk:
|
|
324
|
+
break
|
|
325
|
+
count += len(self._chunk)
|
|
326
|
+
if count > record.byte_count:
|
|
327
|
+
exc = ResultFormatError('原始BLF字节数超过索引')
|
|
328
|
+
self._fail(exc)
|
|
329
|
+
raise exc
|
|
330
|
+
digest.update(self._chunk)
|
|
331
|
+
if self._output_fd is not None:
|
|
332
|
+
_write_all(self._output_fd, self._chunk)
|
|
333
|
+
if count != record.byte_count or digest.hexdigest() != record.sha256.lower():
|
|
334
|
+
exc = ResultFormatError('原始BLF字节数或SHA与索引不符')
|
|
335
|
+
self._fail(exc)
|
|
336
|
+
raise exc
|
|
337
|
+
if self._output_fd is not None:
|
|
338
|
+
self._output_fd.flush()
|
|
339
|
+
self._close_fd('_output_fd')
|
|
340
|
+
self._close_fd('_input_fd')
|
|
341
|
+
# 发布字节也以真实文件回读核验,不能只凭write返回长度宣称副本正确。
|
|
342
|
+
if destination is not None:
|
|
343
|
+
self._check_copy(destination, record.byte_count, record.sha256)
|
|
344
|
+
self._chunk = None
|
|
345
|
+
_release_owned_ram(self, self._io_cost, '_io_cost')
|
|
346
|
+
|
|
347
|
+
def _check_copy(self, path, expected_bytes, expected_sha):
|
|
348
|
+
"""在已预约IO空间内回读真实发布文件,BLF与索引使用同一有界验证。
|
|
349
|
+
|
|
350
|
+
参数: path为本次新目标Path;expected_bytes/SHA为已封口原事实。返回: None。
|
|
351
|
+
异常: 原打开/read/close/取消或ResultFormatError;当前真实FD留在本owner槽。
|
|
352
|
+
"""
|
|
353
|
+
if self._input_fd is not None or not self._io_cost:
|
|
354
|
+
raise ResultClosedError('发布文件回读需空输入槽和已预约IO空间')
|
|
355
|
+
self._input_fd = path.open('rb', buffering=0)
|
|
356
|
+
digest, count = sha256(), 0
|
|
357
|
+
while True:
|
|
358
|
+
self._chunk = self._input_fd.read(_CHUNK_BYTES)
|
|
359
|
+
if not self._chunk:
|
|
360
|
+
break
|
|
361
|
+
count += len(self._chunk)
|
|
362
|
+
if count > expected_bytes:
|
|
363
|
+
raise ResultFormatError('发布文件字节数超过封口事实')
|
|
364
|
+
digest.update(self._chunk)
|
|
365
|
+
if count != expected_bytes or digest.hexdigest() != expected_sha.lower():
|
|
366
|
+
raise ResultFormatError('发布文件字节数或SHA与封口事实不符')
|
|
367
|
+
self._close_fd('_input_fd')
|
|
368
|
+
self._chunk = None
|
|
369
|
+
|
|
370
|
+
def append(self, record):
|
|
371
|
+
"""预付索引RAM/累计spool,核实际文件后完整写一行再推进计数。
|
|
372
|
+
|
|
373
|
+
参数: record为本仓当前索引的RawExportRecord。返回: None。
|
|
374
|
+
异常: 原归属/预算/文件/编码/取消;开始后的失败poison,原BLF费用不重复预约。
|
|
375
|
+
"""
|
|
376
|
+
self._require('building')
|
|
377
|
+
try:
|
|
378
|
+
self._relation(record, self.record_count)
|
|
379
|
+
_reserve_owned_ram(self, _ROW_COST, '_append_cost')
|
|
380
|
+
self._payload = encode_packet(_packet(record)) + b'\n'
|
|
381
|
+
before = self._budget.spool_bytes
|
|
382
|
+
try:
|
|
383
|
+
self._budget.reserve_spool(len(self._payload))
|
|
384
|
+
finally:
|
|
385
|
+
if self._budget.spool_bytes == before + len(self._payload):
|
|
386
|
+
self._spool_bytes += len(self._payload)
|
|
387
|
+
if record.status == 'exported':
|
|
388
|
+
self._file(record)
|
|
389
|
+
_write_all(self._writer, self._payload)
|
|
390
|
+
self._digest.update(self._payload)
|
|
391
|
+
self.inventory_bytes += len(self._payload)
|
|
392
|
+
self.record_count += 1
|
|
393
|
+
self.file_count += int(record.status == 'exported')
|
|
394
|
+
self._payload = None
|
|
395
|
+
_release_owned_ram(self, self._append_cost, '_append_cost')
|
|
396
|
+
except BaseException as exc:
|
|
397
|
+
self._fail(exc)
|
|
398
|
+
raise
|
|
399
|
+
|
|
400
|
+
def seal(self):
|
|
401
|
+
"""真实关闭索引writer并固定流SHA;零记录亦可封口。
|
|
402
|
+
|
|
403
|
+
参数: 无。返回: None。异常: 原flush/close/取消,失败不能冒充sealed。
|
|
404
|
+
"""
|
|
405
|
+
self._require('building')
|
|
406
|
+
try:
|
|
407
|
+
self._writer.flush()
|
|
408
|
+
self._close_fd('_writer')
|
|
409
|
+
self.sha256, self.state = self._digest.hexdigest(), 'sealed'
|
|
410
|
+
except BaseException as exc:
|
|
411
|
+
self._fail(exc)
|
|
412
|
+
raise
|
|
413
|
+
|
|
414
|
+
def iter_records(self):
|
|
415
|
+
"""创建有限独立索引reader,未返回构造始终在本父pending槽可达。
|
|
416
|
+
|
|
417
|
+
参数: 无。返回: 逐条RawExportRecord迭代器。异常: 原预算/打开/登记/取消及状态错误。
|
|
418
|
+
"""
|
|
419
|
+
self._require('sealed')
|
|
420
|
+
if self._pending_reader is not None:
|
|
421
|
+
raise ResultClosedError('原始导出仓有未返回reader待清理')
|
|
422
|
+
try:
|
|
423
|
+
reader = _RawExportReader(self)
|
|
424
|
+
self._pending_reader = None
|
|
425
|
+
return reader
|
|
426
|
+
except BaseException as exc:
|
|
427
|
+
self._fail(exc)
|
|
428
|
+
raise
|
|
429
|
+
|
|
430
|
+
def copy_to(self, destination):
|
|
431
|
+
"""向新发布根独占创建原始目录与索引,逐条核验复制现成BLF。
|
|
432
|
+
|
|
433
|
+
参数: destination为Path;根可已有普通结果表,raw_segments及索引必须均不存在。
|
|
434
|
+
返回: 目标raw_segments.jsonl Path。异常: 原路径/预算/IO/取消或完整性错误;
|
|
435
|
+
输出失败保本次FD责任及部分文件,不覆盖已有工件或关闭sealed输入;
|
|
436
|
+
入口先恢复上次复制,持续关闭失败时不得覆盖旧槽或创建下个目标。
|
|
437
|
+
"""
|
|
438
|
+
self._require('sealed')
|
|
439
|
+
self.recover_copy()
|
|
440
|
+
if not isinstance(destination, Path):
|
|
441
|
+
raise TypeError('原始导出发布根需要Path')
|
|
442
|
+
if sum(len(part) for part in destination.parts) > MAX_WIRE_BYTES:
|
|
443
|
+
raise ValueError('原始导出发布路径超过有界能力')
|
|
444
|
+
target = destination.resolve()
|
|
445
|
+
if any(part.casefold() == 'refprojects' for part in target.parts):
|
|
446
|
+
raise ValueError('原始导出发布禁止RefProjects')
|
|
447
|
+
raw_path, inventory = target / 'raw_segments', target / 'raw_segments.jsonl'
|
|
448
|
+
if raw_path.exists() or inventory.exists():
|
|
449
|
+
raise FileExistsError('原始导出发布目录或索引已存在')
|
|
450
|
+
try:
|
|
451
|
+
_reserve_owned_ram(self, _ROW_COST + 32 * len(str(target)), '_copy_cost')
|
|
452
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
453
|
+
raw_path.mkdir(exist_ok=False)
|
|
454
|
+
self._inventory_fd = inventory.open('xb', buffering=0)
|
|
455
|
+
# 本次临时reader先装独立copy槽;其预约/关闭取消不破坏其他已封口输入。
|
|
456
|
+
self._copy_reader = _RawExportReader(self, copy=True)
|
|
457
|
+
digest, count, files = sha256(), 0, 0
|
|
458
|
+
# reader只交付当前一行;不累计文件路径或导出记录列表。
|
|
459
|
+
for record in self._copy_reader:
|
|
460
|
+
if record.status == 'exported':
|
|
461
|
+
self._file(record, target / record.file_name)
|
|
462
|
+
files += 1
|
|
463
|
+
self._payload = encode_packet(_packet(record)) + b'\n'
|
|
464
|
+
_write_all(self._inventory_fd, self._payload)
|
|
465
|
+
digest.update(self._payload)
|
|
466
|
+
self._payload = None
|
|
467
|
+
count += 1
|
|
468
|
+
if (not self._copy_reader.verified_eof or count != self.record_count
|
|
469
|
+
or files != self.file_count or digest.hexdigest() != self.sha256):
|
|
470
|
+
exc = ResultFormatError('原始导出复制索引未完整匹配封口事实')
|
|
471
|
+
self._fail(exc)
|
|
472
|
+
raise exc
|
|
473
|
+
self._copy_reader = None
|
|
474
|
+
self._inventory_fd.flush()
|
|
475
|
+
self._close_fd('_inventory_fd')
|
|
476
|
+
_reserve_owned_ram(self, _IO_COST, '_io_cost')
|
|
477
|
+
self._check_copy(inventory, self.inventory_bytes, self.sha256)
|
|
478
|
+
_release_owned_ram(self, self._io_cost, '_io_cost')
|
|
479
|
+
_release_owned_ram(self, self._copy_cost, '_copy_cost')
|
|
480
|
+
return inventory
|
|
481
|
+
except BaseException as exc:
|
|
482
|
+
# 输入reader或原BLF摘要错误可已poison父;输出故障只收回本次复制责任。
|
|
483
|
+
exc.raw_export_store_cleanup_owner = self
|
|
484
|
+
for attempt in range(2):
|
|
485
|
+
try:
|
|
486
|
+
self._close_copy_resources()
|
|
487
|
+
break
|
|
488
|
+
except BaseException as cleanup:
|
|
489
|
+
exc.add_note(f'原始导出复制清理第{attempt + 1}次失败: {type(cleanup).__name__}')
|
|
490
|
+
raise
|
|
491
|
+
|
|
492
|
+
def recover_copy(self):
|
|
493
|
+
"""仅恢复上次输出复制的真实责任,保sealed固定输入及其他独立reader。
|
|
494
|
+
|
|
495
|
+
参数: 无。返回: None;copy_to入口会自动调用,调用方也可显式恢复。
|
|
496
|
+
异常: 原FD/reader/费用关闭错误或状态错误;持续失败保最高store与原槽,
|
|
497
|
+
不把整个输入仓置关闭中,不覆盖上次复制尚未释放的资源。
|
|
498
|
+
"""
|
|
499
|
+
self._require('sealed')
|
|
500
|
+
self._close_copy_resources()
|
|
501
|
+
|
|
502
|
+
def _close_copy_resources(self):
|
|
503
|
+
"""关闭本次copy子reader和FD,完全释放后再清当前缓冲与复制费用。
|
|
504
|
+
|
|
505
|
+
参数: 无。返回: None;不操作固定费、原索引writer或其他独立reader。
|
|
506
|
+
异常: 首个真实关闭/抵销错误,副错记note;最高store保存未完成实际槽。
|
|
507
|
+
"""
|
|
508
|
+
failure = None
|
|
509
|
+
if self._copy_reader is not None:
|
|
510
|
+
try:
|
|
511
|
+
self._copy_reader.close()
|
|
512
|
+
except BaseException as exc:
|
|
513
|
+
failure = exc
|
|
514
|
+
finally:
|
|
515
|
+
if self._copy_reader.closed:
|
|
516
|
+
self._copy_reader = None
|
|
517
|
+
for slot in ('_input_fd', '_output_fd', '_inventory_fd'):
|
|
518
|
+
try:
|
|
519
|
+
self._close_fd(slot)
|
|
520
|
+
except BaseException as exc:
|
|
521
|
+
if failure is None:
|
|
522
|
+
failure = exc
|
|
523
|
+
else:
|
|
524
|
+
failure.add_note('原始导出本次复制FD关闭附加失败: ' + type(exc).__name__)
|
|
525
|
+
if self._copy_reader is None and all(getattr(self, slot) is None for slot in ('_input_fd', '_output_fd', '_inventory_fd')):
|
|
526
|
+
self._payload = self._chunk = None
|
|
527
|
+
for slot in ('_io_cost', '_copy_cost'):
|
|
528
|
+
try:
|
|
529
|
+
_release_owned_ram(self, getattr(self, slot), slot)
|
|
530
|
+
except BaseException as exc:
|
|
531
|
+
if failure is None:
|
|
532
|
+
failure = exc
|
|
533
|
+
else:
|
|
534
|
+
failure.add_note('原始导出本次复制费用抵销附加失败: ' + type(exc).__name__)
|
|
535
|
+
if failure is not None:
|
|
536
|
+
failure.raw_export_store_cleanup_owner = self
|
|
537
|
+
raise failure
|
|
538
|
+
|
|
539
|
+
def close(self):
|
|
540
|
+
"""关闭全部自有FD/reader并抵销自有RAM,文件与累计spool保留。
|
|
541
|
+
|
|
542
|
+
参数: 无。返回: None,完成后幂等。异常: 首个真实关闭/抵销错误,副错记note;
|
|
543
|
+
持续故障保原槽/最高owner,不能从借用账本总额倒推或多扣费用。
|
|
544
|
+
"""
|
|
545
|
+
if self._closed:
|
|
546
|
+
return
|
|
547
|
+
self._closing = True
|
|
548
|
+
if self.state == 'building':
|
|
549
|
+
self.state = 'failed'
|
|
550
|
+
failure = None
|
|
551
|
+
# pending与活登记可短暂指向同一真实子;先pending,成功后从登记中解除。
|
|
552
|
+
readers = []
|
|
553
|
+
for reader in (self._pending_reader, self._copy_reader, *tuple(self._readers or ())):
|
|
554
|
+
if reader is not None and reader not in readers:
|
|
555
|
+
readers.append(reader)
|
|
556
|
+
for reader in readers:
|
|
557
|
+
try:
|
|
558
|
+
reader.close()
|
|
559
|
+
except BaseException as exc:
|
|
560
|
+
if failure is None:
|
|
561
|
+
failure = exc
|
|
562
|
+
else:
|
|
563
|
+
failure.add_note('原始导出reader关闭附加失败: ' + type(exc).__name__)
|
|
564
|
+
if self._copy_reader is not None and self._copy_reader.closed:
|
|
565
|
+
self._copy_reader = None
|
|
566
|
+
for slot in ('_writer', '_input_fd', '_output_fd', '_inventory_fd'):
|
|
567
|
+
try:
|
|
568
|
+
self._close_fd(slot)
|
|
569
|
+
except BaseException as exc:
|
|
570
|
+
if failure is None:
|
|
571
|
+
failure = exc
|
|
572
|
+
else:
|
|
573
|
+
failure.add_note('原始导出FD关闭附加失败: ' + type(exc).__name__)
|
|
574
|
+
if (self._pending_reader is None and not self._readers and self._copy_reader is None
|
|
575
|
+
and all(getattr(self, slot) is None for slot in ('_writer', '_input_fd', '_output_fd', '_inventory_fd'))):
|
|
576
|
+
self._payload = self._chunk = None
|
|
577
|
+
for slot in ('_append_cost', '_io_cost', '_copy_cost', '_fixed_cost'):
|
|
578
|
+
try:
|
|
579
|
+
_release_owned_ram(self, getattr(self, slot), slot)
|
|
580
|
+
except BaseException as exc:
|
|
581
|
+
if failure is None:
|
|
582
|
+
failure = exc
|
|
583
|
+
else:
|
|
584
|
+
failure.add_note('原始导出费用抵销附加失败: ' + type(exc).__name__)
|
|
585
|
+
if self._held_cost == 0:
|
|
586
|
+
self._closed = True
|
|
587
|
+
if failure is not None:
|
|
588
|
+
failure.raw_export_store_cleanup_owner = self
|
|
589
|
+
raise failure
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
class _RawExportReader:
|
|
593
|
+
"""拥有单个索引位置/摘要和固定读槽;完整EOF与成功关闭才verified_eof。
|
|
594
|
+
|
|
595
|
+
copy模式只把临时资源错误交本次复制恢复,输入格式/摘要破坏仍poison父仓。
|
|
596
|
+
"""
|
|
597
|
+
|
|
598
|
+
def __init__(self, owner, *, copy=False):
|
|
599
|
+
"""先装父pending槽,再付费打开/登记真实reader。
|
|
600
|
+
|
|
601
|
+
参数: owner为活sealed仓;copy为内部临时复制模式,直接先装父_copy_reader槽。
|
|
602
|
+
返回: 独立reader。异常: 原预算/打开/登记/取消;真实父槽始终保未返回self。
|
|
603
|
+
"""
|
|
604
|
+
self.owner, self._budget = owner, owner.budget
|
|
605
|
+
self._copy = copy
|
|
606
|
+
self.handle = self._digest = None
|
|
607
|
+
self._fixed_cost = self._held_cost = self._count = self._files = self._bytes = 0
|
|
608
|
+
self.closed = self._closing = self.verified_eof = False
|
|
609
|
+
if copy:
|
|
610
|
+
owner._copy_reader = self
|
|
611
|
+
else:
|
|
612
|
+
owner._pending_reader = self
|
|
613
|
+
# 仅索引reader允许8192字节有限预读;buffer/对象另付16384,原行限及真EOF不变。
|
|
614
|
+
# BLF分块复制与写端不改,同一handle始终拥有buffer及真实raw FD。
|
|
615
|
+
_reserve_owned_ram(self, _ROW_COST + 16384, '_fixed_cost')
|
|
616
|
+
self._digest = sha256()
|
|
617
|
+
try:
|
|
618
|
+
self.handle = owner.inventory_path.open('rb', buffering=8192)
|
|
619
|
+
except FileNotFoundError as exc:
|
|
620
|
+
# 普通工厂原已有_fail;copy专用工厂也须把源索引消失归为输入完整性失效。
|
|
621
|
+
if copy:
|
|
622
|
+
owner._fail(exc)
|
|
623
|
+
raise
|
|
624
|
+
owner._readers.add(self)
|
|
625
|
+
|
|
626
|
+
def __iter__(self):
|
|
627
|
+
"""保持独立原位置。参数: 无。返回: self。异常: 无,不重新开文件。"""
|
|
628
|
+
return self
|
|
629
|
+
|
|
630
|
+
def __next__(self):
|
|
631
|
+
"""逐行校索引归属/序号,真实EOF核完整SHA、条数、文件数与字节数后关闭。
|
|
632
|
+
|
|
633
|
+
参数: 无。返回: RawExportRecord。异常: 真实StopIteration或原格式/关闭/取消;
|
|
634
|
+
输入损坏poison父;copy临时资源失败交本次恢复,原异常/取消对象保持。
|
|
635
|
+
"""
|
|
636
|
+
if self.closed:
|
|
637
|
+
raise StopIteration
|
|
638
|
+
self.owner._require('sealed')
|
|
639
|
+
if self._closing:
|
|
640
|
+
raise ResultClosedError('原始导出reader正在清理')
|
|
641
|
+
try:
|
|
642
|
+
payload = self.handle.readline(MAX_WIRE_BYTES + 1)
|
|
643
|
+
if payload:
|
|
644
|
+
if len(payload) > MAX_WIRE_BYTES or not payload.endswith(b'\n'):
|
|
645
|
+
raise ResultFormatError('原始导出索引行超限或缺完整换行')
|
|
646
|
+
if self._count >= self.owner.record_count:
|
|
647
|
+
raise ResultFormatError('原始导出索引出现额外后缀')
|
|
648
|
+
record = _decode(payload[:-1])
|
|
649
|
+
try:
|
|
650
|
+
self.owner._relation(record, self._count)
|
|
651
|
+
except (TypeError, ValueError) as exc:
|
|
652
|
+
raise ResultFormatError('原始导出索引归属或序号非法') from exc
|
|
653
|
+
self._digest.update(payload)
|
|
654
|
+
self._count += 1
|
|
655
|
+
self._files += int(record.status == 'exported')
|
|
656
|
+
self._bytes += len(payload)
|
|
657
|
+
return record
|
|
658
|
+
if (self._count != self.owner.record_count or self._files != self.owner.file_count
|
|
659
|
+
or self._bytes != self.owner.inventory_bytes or self._digest.hexdigest() != self.owner.sha256):
|
|
660
|
+
raise ResultFormatError('原始导出索引EOF数量或SHA不匹配')
|
|
661
|
+
self.close()
|
|
662
|
+
except BaseException as exc:
|
|
663
|
+
if not self._copy or isinstance(exc, ResultFormatError):
|
|
664
|
+
self.owner._fail(exc)
|
|
665
|
+
else:
|
|
666
|
+
exc.raw_export_store_cleanup_owner = self.owner
|
|
667
|
+
raise
|
|
668
|
+
self.verified_eof = True
|
|
669
|
+
raise StopIteration
|
|
670
|
+
|
|
671
|
+
def close(self):
|
|
672
|
+
"""真实关FD、抵销本笔费用并解除父登记后才closed,可持续重试。
|
|
673
|
+
|
|
674
|
+
参数: 无。返回: None。异常: 原close/预算/取消;最高store仍持本实例。
|
|
675
|
+
"""
|
|
676
|
+
if self.closed:
|
|
677
|
+
return
|
|
678
|
+
self._closing = True
|
|
679
|
+
try:
|
|
680
|
+
if self.handle is not None and not self.handle.closed:
|
|
681
|
+
self.handle.close()
|
|
682
|
+
_release_owned_ram(self, self._fixed_cost, '_fixed_cost')
|
|
683
|
+
self.owner._readers.discard(self)
|
|
684
|
+
if self.owner._pending_reader is self:
|
|
685
|
+
self.owner._pending_reader = None
|
|
686
|
+
self.closed = True
|
|
687
|
+
except BaseException as exc:
|
|
688
|
+
exc.raw_export_store_cleanup_owner = self.owner
|
|
689
|
+
raise
|