From 617d11cbb6d9c94bd2d9547fc620fa1af946000e Mon Sep 17 00:00:00 2001 From: Taewoon Kim Date: Sat, 31 Oct 2026 16:11:40 +0900 Subject: [PATCH] native: diag() reads jvector's provider through the engine (#155) ArcadeNative.diag called VectorizationProvider.getInstance() directly. jvector picks its provider once per process, so a diag() before the first database took the choice away from the engine's VectorApiSupport.configureJVectorProvider() (scalar in a native image): Panama (the uncompiled Vector API) on macOS and Windows, which failed the nightly parity legs there on test_the_default_provider_follows_the_shipped_library. Reproduced on Linux x86-64 with the dev wheel: diag() first keeps jvector's own provider after a database and vector index are created; the database first gets DefaultVectorizationProvider. VectorApiSupport.jvectorProvider() (public since engine 26.10.2) runs the engine's choice first. Closes #155 Co-Authored-By: Claude Opus 5.5 --- .../src/main/java/org/humemai/nativelib/ArcadeNative.java | 4 +++- tests/test_native_vector_provider.py | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/native/src/main/java/org/humemai/nativelib/ArcadeNative.java b/native/src/main/java/org/humemai/nativelib/ArcadeNative.java index 4e16cafc..9b5acb91 100644 --- a/native/src/main/java/org/humemai/nativelib/ArcadeNative.java +++ b/native/src/main/java/org/humemai/nativelib/ArcadeNative.java @@ -430,7 +430,9 @@ public static CCharPointer diag(final IsolateThread thread) { sb.append(",\"max_heap\":").append(Runtime.getRuntime().maxMemory()); sb.append(",\"exec_timers_ns\":{\"calls\":").append(T[0]).append(",\"args\":").append(T[1]).append(",\"json\":").append(T[2]) .append(",\"engine\":").append(T[3]).append(",\"reply\":").append(T[4]).append('}'); - final io.github.jbellis.jvector.vector.VectorizationProvider vp = io.github.jbellis.jvector.vector.VectorizationProvider.getInstance(); + // through the engine, never VectorizationProvider.getInstance(): jvector picks its provider once per process, and asked first it + // would pick on its own (Panama, the uncompiled Vector API, where no libjvector ships) before the engine sets the scalar default + final io.github.jbellis.jvector.vector.VectorizationProvider vp = com.arcadedb.utility.VectorApiSupport.jvectorProvider(); sb.append(",\"provider\":"); NativeCodec.quote(sb, vp.getClass().getName()); sb.append(",\"util_support\":"); diff --git a/tests/test_native_vector_provider.py b/tests/test_native_vector_provider.py index 076699bc..3df48665 100644 --- a/tests/test_native_vector_provider.py +++ b/tests/test_native_vector_provider.py @@ -43,7 +43,11 @@ def test_without_the_library_the_scalar_provider_stays(tmp_path): def _provider(tmp_path, value=None) -> str: - """The VectorizationProvider class an isolate of a fresh process runs, with ARCADEDB_VECTOR_PROVIDER unset or set to ``value``.""" + """The VectorizationProvider class an isolate of a fresh process runs, with ARCADEDB_VECTOR_PROVIDER unset or set to ``value``. + + ``diag()`` is the child's first call, before any database: jvector picks its provider once per process, so this also checks that + ``diag()`` leaves the choice to the engine (it picked Panama on macOS and Windows when it asked jvector first). + """ env = {k: v for k, v in os.environ.items() if k != "ARCADEDB_VECTOR_PROVIDER"} env["ARCADEDB_LOG_DIR"] = str(tmp_path / "log") if value is not None: