Repository navigation
perf(python): accelerate Dataset Index metadata lookups - #959
Merged
ColinLeeo merged 4 commits intoSep 17, 2026
Merged
Conversation
The Cython fast paths indexed the mmap with child ranges read from the index records without validating them, so a corrupt or hand-crafted .tsidx could read past the mapping and crash the interpreter (SIGSEGV/SIGBUS) instead of raising, which the previous pure-Python path did via record(). Validate the device/column/series child ranges the same way describe_series and find_series_span already do, and take ids as signed values so negative ids keep raising IndexError instead of OverflowError. Also drop the now-unused pure-Python _find_child, retarget the hash-collision test at the production Cython lookup (the old test only exercised that dead helper), and skip the dataclass-slots assertion on Python 3.9 where dataclasses do not support slots.
The descriptor cache size and its hit/miss counters were exposed through TSFILE_DATAFRAME_DESCRIPTOR_CACHE_SIZE / _STATS, adding process-wide configuration surface plus a stats branch on every lookup for a bounded process-local cache that already has a sane budget. Keep the historical 4096-entry default and restore the unconditional cache reads.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Unchecked string-pool references can overflow and cause out-of-bounds mmap access on damaged indexes.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR accelerates Dataset Index metadata lookups with a Cython mmap kernel while preserving the existing index format.
Changes:
- Added optimized lookup and string-decoding paths.
- Updated runtime metadata consumers and descriptor memory usage.
- Added build integration and corruption regression tests.
File summaries
| File | Description |
|---|---|
python/tsfile/dataset/runtime.py |
Uses optimized metadata accessors. |
python/tsfile/dataset/index.py |
Routes index access through the kernel. |
python/tsfile/dataset/_index.pyx |
Implements the mmap lookup kernel. |
python/tests/test_dataset_index.py |
Adds lookup and corruption regression tests. |
python/setup.py |
Builds the new Cython extension. |
Review details
Suppressed comments (1)
python/tsfile/dataset/_index.pyx:532
string_id + 1is evaluated using thePy_ssize_targument, so passingsys.maxsizecan overflow before the bounds check on platforms where that is the maximum signed size. That can bypass the check and lead to an out-of-bounds mmap read; use a subtraction-free upper-bound comparison such asstring_id >= string_count - 1.
if string_id < 0 or string_id + 1 >= string_count:
- Files reviewed: 5/5 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| cdef uint32_t start | ||
| cdef uint32_t end | ||
| cdef Py_ssize_t index | ||
| if string_id + 1 >= string_count: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR reduces CPython overhead in the mmap-backed Python Dataset Index and runtime metadata paths without changing the Dataset Index (
.tsidx) format or introducing dataset-sized worker maps: the new kernel owns no index-sized state and only reads the existing read-only mmap.Changes
tsfile.dataset._index(IndexLookup), a Cython kernel over the existing mmap, to remove Python tuple/bytes allocation from the hot paths:MappedDatasetIndexnow exposes scalar accessors (describe_series,find_series_span,locator_metadata,prepared_locator_metadata,device_route,table_name_id,column_name_id,device_time_bounds,series_identity) and routesfind_device_id/find_column_id/find_series_id/stringthrough the kernel. The extension is built bypython/setup.pyalongside the existing Cython extensions, and the now-unused pure-Python_find_childis gone.describe_seriesandfind_series_spanalready used), and ids are read as signed values. A corrupt.tsidxused to be able to walk past the mapping and crash the interpreter instead of raising, and negative ids raisedOverflowErrorrather thanIndexError.RuntimeSeriesShardandRuntimeSeriesDescriptoruseslotson Python 3.10+ to cut per-object memory.DatasetRuntimeandRuntimeSeriesReaderuse the fast metadata paths.Results
Synthetic microbenchmarks compared with the previous pure-Python lookups:
find_device_idfind_column_idfind_series_iddescribe_series_span_identityThese are local operation-level results. End-to-end DDP training throughput still requires a remote A/B benchmark with the rebuilt wheel.
Validation
New regression tests cover behavior that was previously untested: a corrupt index whose child range points outside its section must raise
IndexError(the pre-fix build crashed on the same input), negative ids must raiseIndexError, and a stored hash match with different bytes must still be rejected by the full-byte comparison.