bindings/python: align max_connections default with engine #5352 (supersedes #5355) - #5617
Conversation
…-20) Regenerated by make-upstream-pr-branch.sh: bindings/python brought to the fork's main state. Scope: the minimum needed to reproduce the wheel build and run the tests and examples.
…ample 11 ArcadeDB applies maxConnections verbatim to every layer while hnswlib-derived backends double it at the base layer, so one shared flag built ArcadeDB at degree 32 and faiss, lancedb, pgvector, qdrant and milvus at an effective 64. Convert to hnswlib M at each call site and report the converted value.
The invocation pinned --max-connections 16, so the aligned default never ran end to end and the smoke-test index built at half the intended density.
The package was renamed from real-ladybug to ladybug upstream. The version jump crosses four minors on a 0.x package and no CI job exercises this path, so pin it for reproducible benchmark runs.
Both announced 256 while creating the index through SQL that sets neither beamWidth nor maxConnections, so both built at the engine default of 100.
…e default The wrapper default shadows the engine default because create_vector_index always calls withMaxConnections. Read LSMVectorIndexMetadata through JPype and compare, so the two cannot drift apart again.
|
Tick the box to add this pull request to the merge queue (same as
|
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Documentation | 4 minor |
| Security | 7 high |
🟢 Metrics 8 complexity
Metric Results Complexity 8
🟢 Coverage ∅ diff coverage · -5.72% coverage variation
Metric Results Coverage variation ✅ -5.72% coverage variation Diff coverage ✅ ∅ diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (2f985b8) 140939 105044 74.53% Head commit (18c00b8) 174076 (+33137) 119782 (+14738) 68.81% (-5.72%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#5617) 0 0 ∅ (not applicable) Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
PR Review: align max_connections default with engine (#5352, supersedes #5355) Reviewed the full diff and cross-checked against the engine. Clean, well-reasoned change with good tests. What is correct and verified
Minor observations (non-blocking)
Coverage Nice work preserving @tae898 authorship and layering the maintainer follow-ups as separate, well-described commits. |
|
Thanks for picking this up, and for keeping the authorship on the original commit. The example 11 catch is the one that matters. My change would have shipped a comparison of ArcadeDB at degree 32 against an effective 64 on the hnswlib-derived backends, which is exactly what #5352 was about, one level down. The test reading One scope note, not a blocker: the beam width prints in examples 03 and 06 are unrelated to Happy for this to supersede #5355. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5617 +/- ##
============================================
+ Coverage 65.63% 67.00% +1.36%
============================================
Files 1717 1718 +1
Lines 140939 142084 +1145
Branches 30174 30521 +347
============================================
+ Hits 92506 95202 +2696
+ Misses 35936 34211 -1725
- Partials 12497 12671 +174 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Examples 03 and 06 printed the JVector parameters as literals while creating the index through SQL that sets only dimensions and similarity, so the output would go stale the next time an engine default moved. Read the values off the created index instead. Also record why the Ladybug pin exists.
|
Addressed observation 1, took observation 3 as a code comment, and left observation 2 alone. Pushed as 18c00b8. 1. Hardcoded prints in examples 03/06 — fixed rather than left. You are right that this is the same drift class the PR exists to fix, and leaving a known instance of it in the same PR would be inconsistent. Both examples now read the values off the created index via the public Example 03 needed a reorder: the parameter block printed before the Verification, since these are the two examples with the weakest coverage:
Full suite still 351 passed / 11 skipped. 2. 3. Ladybug pin rot. Added a comment at both pin sites recording why the pin exists (pre-1.0, no CI coverage) and to re-check it when refreshing published results. A comment beats a tracking issue here since it is visible exactly where someone would bump it. One thing worth separating out, unrelated to this diff: while building a wheel to verify the drift test I hit |
ReviewReviewed the full diff against the codebase. This is a tidy, well-reasoned PR: it's Python-bindings/examples/CI only, no engine changes, and each commit is narrowly scoped with a clear rationale. Nice work, and the "prove the test fails before trusting it" note in the description is exactly the right discipline. I verified the load-bearing details against the repo:
Minor observations (non-blocking)
Test coverageGood. The two new test files cover both the conversion helper and the wrapper/engine default tie, and both are structured to fail loudly if the two layers drift again — which is exactly the class of bug this PR fixes. The No correctness, performance, or security concerns. LGTM. |
The Docker path's success gate was `ls dist/*.whl`, which asks whether a wheel exists rather than whether this run made one. Nothing cleans dist/, so a wheel left by any earlier build satisfied it: an export stage that yielded nothing still printed the success banner and exited 0, handing back a stale wheel that looks freshly built. build-native.sh already avoided this by clearing the directory first (rm -f "$DIST_DIR"/*.whl); the Docker branch had no equivalent. Reported by @robfrank while building a wheel to verify a test on ArcadeData#5617. Compare wheel identities across the extraction instead of clearing, so wheels deliberately kept for other platforms survive a build. A same-named wheel (a rebuild of the same version) is accepted only when the extraction actually rewrote it, tested against a marker file stamped before the build starts; `test -nt` rather than `find -newermt` because this script also runs on macOS hosts and the latter is GNU-only. Four states verified in isolation, then end to end: empty dist + no wheel produced -> rc=1 (was rc=1) empty dist + wheel produced -> rc=0 STALE wheel + no wheel produced -> rc=1 (was rc=0, the bug) same-name wheel rewritten by the run -> rc=0 A full Docker build with a planted stale wheel present still exits 0, reports the new 26.8.1.dev0 wheel, and leaves the planted one untouched. Note the reported exit-0-on-javac-error case does NOT reproduce on this line: injecting a deliberate javac error into the bridge sources fails the RUN and build.sh exits 1. Only the no-wheel-produced path was reachable, and it is the one fixed here.
|
Correcting myself on the build tooling note at the end of my previous comment. I said I had run it as a compound command: so the status I read back was the trailing @tae898 is right in 5a8445e that the javac case fails properly: injecting a javac error does fail the build. Apologies for sending you after a defect that was not there. What I actually hit was the narrower thing that commit fixes: a failed build leaves the previous wheel in Two related things I ran into on the same path, in case they are useful and separate from that commit:
None of this affects the diff under review here. |
|
Merged, thanks. Reading the metadata back in examples 03/06 is a better fix than the one I had in mind, and reordering 03 so the block reports what was built rather than what was intended is the part I would not have thought to do. Before you spend time filing the The stale wheel is real, and fixed. The Docker path's success gate was Fixed in humemai/arcadedb-embedded-python@5a8445e, which I will carry into the next bindings PR here rather than opening a separate one. It compares wheel identities across the extraction instead of clearing the directory, so wheels deliberately kept for other platforms survive a build, and a same-named wheel is accepted only when the extraction actually rewrote it (marker file plus
A full Docker build with a stale wheel planted in The exit-0-on-javac-errors half does not reproduce for me. I put a deliberately broken So either those two runs failed somewhere I have not found, or the exit 0 you saw was the stale-wheel gate downstream of a build that had already gone wrong. If you still have the scrollback, the last 20 lines and the platform would settle it. If it was the stale wheel, the fix above covers it and there is nothing left to file. |
Supersedes #5355, preserving @tae898's original commit and authorship. Opened as a separate PR only because
humemaiis an organization-owned fork, and GitHub does not honor maintainer edits on org-owned forks, so the fixes could not be pushed to the original branch.Follows up #5352. The Python wrapper (
create_vector_index) carried its ownmax_connections=16default, which shadowed the engine's new default of 32 because the wrapper always callswithMaxConnections. This aligns the wrapper and documents the semantics:maxConnectionsis a Vamana per-layer degree, not hnswlibM, so reproducing an hnswlib configuration takes2*M.Original contribution by @tae898
real_ladybugtoladybugMaintainer follow-ups
--max-connectionsflag fed six backends with two different meanings. ArcadeDB applies the value verbatim to every layer; faiss, lancedb, pgvector, qdrant and milvus are hnswlib-derived and double it at the base layer. At the new default that compared ArcadeDB at degree 32 against an effective 64 elsewhere. Ahnsw_m_from_max_connections()helper now converts at each call site, and the fourhnsw_mentries in the results metadata report the converted value.bindings/python/testshad no reference tomax_connections, which is how the wrapper and engine separated in the first place. The new test readsLSMVectorIndexMetadata.maxConnectionsthrough JPype and asserts the wrapper default equals it, rather than asserting a literal 32.--max-connections 16, so the aligned default never ran end to end.ladybugpinned to 0.19.0. The rename crosses four minors on a 0.x package and no CI job exercises that path.Verification
Full Python suite against a wheel built from this branch: 351 passed, 11 skipped. Six of the skips are
test_docs_examples.py, which skips becausebindings/python/docsdoes not exist in this repository; those run in the contributor's fork, which accounts for the difference from the 353 reported on #5355.The drift test was proven to fail before being trusted: with the installed default flipped to 16, both new tests fail
assert 16 == 32; restored to 32, all 13 tests in that file pass.Note: the docs updates mentioned in #5355's description live in
humemai/arcadedb-embedded-python. This repository has nobindings/python/docsdirectory, so nothing here covers them.