Repository navigation
Conversation
…int32, float32 columns and null bitmaps, no JSON The columnar entry now reads the caller's buffers in place (an address table of six longs per column) and builds the documents without a text parser. New kinds: s (UTF-8 string as Arrow offsets plus bytes), i (int32), e (float32); Arrow validity bitmaps for nulls. arcadedb_n_insert_cols keeps its single-buffer form and shares the loop. Every length and offset is checked before the first document is built. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ntry when every column maps to a supported kind _native/columnar.py lays out whole columns (int64, float64, bool, int32/float32 for INTEGER/FLOAT properties, UTF-8 strings as Arrow offsets plus bytes, float32 vectors for ARRAY_OF_FLOATS properties, null bitmaps) and hands their addresses to arcadedb_n_insert_colp. insert_many transposes a chunk of same-keyed dict rows into columns; insert_dataframe/insert_arrow keep string and nullable Arrow columns as Arrow arrays. Nested values, mixed-type columns, date-times, decimals, integers past 64 bits and lone surrogates keep the JSON path. Public API unchanged; ARCADEDB_NATIVE_BULK=0 turns the columnar path off. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tae898
marked this pull request as ready for review
October 25, 2026 03:09
tae898
marked this pull request as draft
October 25, 2026 03:11
Author
|
Back to draft on purpose: untimed it is 2.3x (indexed) to 3.5x (no index) faster on 1M mixed documents, but the prototype merges only after the timed laptop A/B (dev1 wheel vs this wheel, ab.py --noise, rule written first: both gating figures need a 95% CI upper end below 0.80). That study is queued right after the running heap study. |
…it B608, test-owned type names) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 25, 2026
Author
|
Closing here: the bindings moved to ArcadeData/arcadedb-python, and this change is merged there as ArcadeData/arcadedb-python#72 (columnar bulk insert by address). The branch stays. |
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.
What
The native wheel's bulk insert no longer has to go through JSON text when every column maps to a supported kind.
arcadedb_n_insert_colpis a new entry point that reads the caller's buffers in place (an address table of six longs per column: data, aux, null bitmap) and builds the documents inside the image without a parser, aHashMapper row or a boxed number.arcadedb_n_insert_colskeeps its single-buffer form (old callers and old libraries keep working) and shares the same loop.The design and the build decision are in the untimed study
.notes/bench/repros/native-json-transport-20261025(JSON text was 43-76% of the native bulk-insert wall on the mixed 1M-document load, rule verdict BUILD). The public API is unchanged and the JVM wheel is untouched.Column kinds
q,d,bi,eINTEGER/FLOAT; otherwise an int32 or float32 column widens toq/d, as the JSON path stores itfdimper rowARRAY_OF_FLOATSsint32 offsets[n+1]plus UTF-8 bytes (Arrow string layout;offsets[0]need not be 0, so a sliced Arrow array crosses without a copy)strcolumns, Arrowstring/large_stringNonein a list column, Arrow nulls, pandas<NA>Every length, offset and bitmap size is checked in the image before the first document is built: a wrong table is an exception with a message, never a fault, and nothing is written. Same transaction contract as before (a transaction opened by the call is committed every
commit_everyrows and rolled back on failure; a caller's transaction is left alone).Where it is used
insert_many: a chunk (10,000 rows) of dicts with the same keys whose columns each hold one value type is transposed to columns and sent by address.insert_columns,insert_dataframe,insert_arrow: string and nullable Arrow columns stay Arrow arrays and cross in place; the declared types of the type are read once per call (the DataFrame path already has them).parallel=True, vertex types throughGraphBatch.ARCADEDB_NATIVE_BULK=0turns the columnar entry off (JSON path), for A/B runs in one image.Tests
tests/test_native_columnar_pack.py(all backends, no native library): the layouts read back from the addresses, null bitmaps, which columns are refused, the address table and header, Arrow offsets of sliced arrays.tests/test_native_columnar_insert.py(collected on native only, perconftest.py): the same data through the JSON path and through the columnar entry on the probe workload's column types (INTEGER, DOUBLE, 20-value category, variable-length text, float32 vectors) viainsert_many,insert_columns,insert_dataframe,insert_arrow, with the stored records compared value by value and type by type; unicode, empty, NUL-containing and 70 KB strings; nulls (list columns and pandas nullable dtypes); int64 edges, NaN and infinities; int32 and float32 columns; vertex types; every fallback case, with a spy on the crossing so a silent fall back cannot pass; duplicate-key failure and rollback on both paths; chunking and commit interval; and calling the entry with a wrong address table, which must give an error and write nothing.test_docs_examples.pyandtest_wheel_packages.py, whose child processes cannot import the package orsetuptoolsoutside an installed wheel (the parity run installs the wheel, seenative-wheel/parity).Status
Ready for review; the timed check is still to come. Done: the image builds (
native-spikeat 8a7d4b9,-march=compatibility, about 2 minutes on the laptop), the native tests above pass against it, a wheel26.10.2.dev1+colstris built from it, and the study's native arms are re-run on that wheel (.notes/bench/repros/native-json-transport-20261025README, Step 3). Untimed and indicative, 1M mixed documents, two runs per arm, one process each, GC logs on: with the UNIQUE index onid,insert_manyof the same dict rows 43.5 s -> 19.0 s and oneinsert_columnscall 15.1 s (the floor is the engine's per-document work plus the commit with the index check, 13.6 s for the numeric and vector columns that already had a binary path); without the index 34.6 s -> 10.0 s and 6.1 s. In-image allocation with the index 15.2 GB -> 9.4 GB. The JSON path inside the new image is as fast as in dev1, so the image change itself costs nothing. These are not speed claims. The timed ab.py study (dev1 wheel against this wheel,rowsandframeloads, rule written first) is prepared in.notes/bench/repros/native-columnar-ab-laptop-20261025and not started; the prototype goes into a preview only if its result says ok and both ratios have the upper end of the 95% CI below 0.80. CI: the native parity run on this branch is the check that matters.🤖 Generated with Claude Code