Repository navigation
feat(ipc): Write dictionary deltas from ArrowIpcWriterWriteArrayViewWithDictionaries - #980
Draft
rustyconover wants to merge 2 commits into
Draft
rustyconover wants to merge 2 commits into
rustyconover wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #980 +/- ##
==========================================
- Coverage 78.52% 78.52% -0.01%
==========================================
Files 106 106
Lines 17195 17381 +186
Branches 2064 2121 +57
==========================================
+ Hits 13502 13648 +146
- Misses 2431 2439 +8
- Partials 1262 1294 +32 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rustyconover
force-pushed
the
feat/ipc-writer-dictionary-deltas
branch
2 times, most recently
from
October 20, 2026 22:34
09d8978 to
cf1f753
Compare
…wWithDictionaries ArrowIpcWriterWriteArrayViewWithDictionaries() wrote every dictionary before every RecordBatch: its input is borrowed, so it couldn't compare a dictionary with the previous batch's by address as ArrowIpcWriterWriteArrayStream() does. The writer now keeps a copy of each dictionary it writes and compares the next batch's values with it, writing only dictionaries that changed (and those whose values contain a nested dictionary that was written). In a file, batches whose dictionaries are unchanged can now be written this way. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ithDictionaries When a batch's dictionary starts with the values last written for its ID, the writer now writes only the appended values, as a delta DictionaryBatch, instead of replacing the whole dictionary. This only applies to streams: a file does not support deltas. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
rustyconover
force-pushed
the
feat/ipc-writer-dictionary-deltas
branch
from
October 26, 2026 16:05
cf1f753 to
6bc6f0c
Compare
This branch has not been deployed
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.
With #979,
ArrowIpcWriterWriteArrayViewWithDictionaries()skips a dictionary that is unchanged since the last batch, but any change still replaces the whole dictionary. A common change is a dictionary that only grows: a producer encodes each batch against a dictionary that it appends new values to. Arrow streams can send just the appended values as a delta (DictionaryBatch.isDelta), which nanoarrow's reader supports since #955.When a batch's dictionary is longer than the one last written for its ID and starts with the same values, the writer now writes only the appended values, as a delta. To check this, it copies the first
nvalues, wherenis the length of the saved copy, and compares that with the saved copy. On a match, it copies the appended values and writes them as a delta, then appends them to the prefix copy, which becomes the new saved copy. Anything else is a replacement, as before.Deltas are only written to streams. In a file, a dictionary that grew is a replacement and returns ENOTSUP, matching #928, whose writer doesn't write deltas to files. A dictionary that is written again because a nested dictionary changed is written in full.
Cost: the same benchmark as #979, 1000 batches of 2048 rows,
dictionary<int32, string>, written to a memory buffer (Release, Linux aarch64; best of 3):Tests (
writer_test.cc):WriteArrayViewWithDictionariesDeltas: dictionaries[foo, bar],[foo, bar, baz],[foo, bar, baz],[foo, qux]write a full dictionary, a delta, nothing, and a replacement (isDelta0, 1, 0). Read back with nanoarrow and Arrow C++.WriteArrayViewWithDictionariesNullableDelta:int64values[1, null, 3]growing to[1, null, 3, null, 5], where the delta starts partway through a byte of the validity bitmap.WriteArrayViewWithDictionariesNoDeltaInFile: in a file, a dictionary that grew returns ENOTSUP.ctestpasses (Linux aarch64, Debug, 881 tests withNANOARROW_BUILD_TESTS_WITH_ARROW), and 406 tests under ASan/UBSan with clang. The writer tests are clean under valgrind. The changed files are formatted with clang-format 16.0.6, the pre-commit version.This PR's code and description were written by AI (Claude Code) and reviewed by a human maintainer.
🤖 Generated with Claude Code
Validation after rebasing (October 26): macOS arm64 Debug, 429 CTest cases, no failures; 16 compression cases skipped because compression is disabled in this build.