Repository navigation
Conversation
…r entry (kinds I Q E D) A chunk with a list-of-ints column (the sparse-vector tokens) or a ragged list-of-floats column was refused by columnar.pack and sent as one JSON text. The columnar entry now carries such columns as int32 element offsets plus one buffer of elements, like a string column: I (int32, stored int[]), E (float32, float[]), Q (int64, list of Long), D (float64, list of Double), chosen from the declared property type so the engine stores what the JSON text stores. A library without the new probe entry arcadedb_n_colp_lists keeps lists on the JSON path (lib.COLP_LISTS, ARCADEDB_NATIVE_COLP_LISTS=0 turns it off). Closes #231. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…crossed rows once) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
First timed run (native wheel against native wheel: arm A = main's CI native wheel, arm B = this PR's CI native wheel, A/A control; laptop timed lane,
Clean pairs per figure: 11; every run passed its arm check (each arm ran its own library and crossed its own entries). By the rule written before the run this is GRAY: both sparse loads are well below the 0.90 bar, but the plain-column control is outside [0.97, 1.03]. The two arms are different builds of the native library, and plain columns cross the same entry on both, so a moving control says the new library as a whole changed speed, not only the list path; the rule then makes no speed claim. Peak RSS is reported, not gating, and it is higher on this PR. The study declared one confirmatory rerun for a GRAY before the first run (same arms, pins and rule, final). It is queued; both runs will be reported here, and the PR stays draft until it reads. |
Closes #231.
Native
insert_manynow keeps rows with lists of ints or of floats (the token and weight columns of a sparse-vector load, fixed or ragged) on the columnar entryarcadedb_n_insert_colp, instead of sending the whole chunk as one JSON text. Before,columnar._list_columnreturnedNonefor a list of ints, sopackrefused the chunk and_insert_chunkfell through toarcadedb_n_insert_rows.New buffer format (four kinds next to the existing
q d b i e f s): the data buffer isint32 offsets[n+1]counted in elements (the same shape as a string column's offsets;offsets[0]need not be 0; a null or empty row has equal neighbours) and the aux buffer holds the elements, native-endian.Iis int32 elements stored asint[](property declaredARRAY_OF_INTEGERS),Eis float32 stored asfloat[](declaredARRAY_OF_FLOATS),Qis int64 stored as a list of Long andDis float64 stored as a list of Double (undeclared or declaredLIST), so the engine stores what the JSON text parses to today. Optional Arrow null bitmaps work as for the other kinds. The Java side checks every offset against the element bytes before the first document is built, so a wrong table is an exception and nothing is written.A library without the decoder is detected by the missing probe entry
arcadedb_n_colp_lists(lib.COLP_LISTS, alsoARCADEDB_NATIVE_COLP_LISTS=0), and keeps such columns on the JSON path. Anything the kinds cannot carry unchanged still goes the JSON way: mixed int and float elements, bools, nested lists, tuples, NaN or an infinity, an int past 64 bits, an int outside int32 forARRAY_OF_INTEGERS, ints in anARRAY_OF_FLOATSragged list, another declared array type. A fixed-length float list forARRAY_OF_FLOATSkeeps its float32 matrix.Files:
native/.../BulkOps.java(decoder and validation),ArcadeNative.java(probe entry),src/arcadedb/_native/columnar.py(_ragged_column),bulk.py,lib.py.Tests (run in CI, no local runs):
tests/test_native_columnar_pack.pycovers the layouts and every refusal;tests/test_native_columnar_insert.pyloads the sparse shapes (fixed and ragged, with anLSM_SPARSE_VECTORindex), every list shape (ARRAY_OF_INTEGERS,ARRAY_OF_FLOATS, declaredLIST, undeclared, None rows, empty rows, int32 and float32 edges), more rows than one chunk, a library without the decoder, and malformed tables. A spy proves the columnar entry ran and no JSON text was sent (arcadedb_n_insert_rowsandarcadedb_n_exec_manycounts are 0), and the stored records are compared with the JSON path value by value, Python type by Python type and by the engine'stype(), plus thevector.sparseNeighborsresults of the two indexes.Draft until CI is green and the timed wheel-vs-wheel A/B (pre-registered under DECISIONS #240 in the maintainer notes) has a verdict. Untimed orientation figures are in the issue.
🤖 Generated with Claude Code