Skip to content

Add Alternator vector search support#145

Open
dkropachev wants to merge 1 commit into
scylladb:mainfrom
dkropachev:vector-1
Open

Add Alternator vector search support#145
dkropachev wants to merge 1 commit into
scylladb:mainfrom
dkropachev:vector-1

Conversation

@dkropachev

@dkropachev dkropachev commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Replaces #87.

This carries the vector search support from #87, scoped to the vector API/client integration work:

  • Add com.scylladb.alternator.vectorsearch request/response support for VectorIndexes, VectorIndexUpdates, VectorSearch, FLOAT32VECTOR, and query scores.
  • Auto-register VectorSearchInterceptor in the sync and async Alternator client builders.
  • Add unit coverage for vector JSON conversion, sync/async response transformation, async query result extraction, checksum/header handling for modified vector responses, and vector integration helpers.
  • Add integration tests that skip cleanly when the target Scylla/Alternator instance does not support vector indexes or has vector store disabled.

Split out of this PR:

  • Demo2 shutdown cleanup: separate PR.
  • Live-nodes polling client shutdown cleanup: separate PR.
  • Compression/vector interceptor chaining: separate stacked PR based on vector-1.

Tests:

  • JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH mvn -q fmt:check
  • JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH mvn -q -Dtest=VectorSearchInterceptorTest,VectorSearchHttpInterceptorTest test
  • JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:$PATH mvn -q test


@Override
public void cancel() {
upstream.cancel();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing to ResponseCompressionInterceptor there is no recording of cancellation. AI says that ResponseCompressionInterceptor.DecompressingSubscriber does it correctly:

private boolean cancelled;

@Override
public void onNext(ByteBuffer byteBuffer) {
    if (isCancelled()) { return; }       // ← stops buffering
    ...
}

@Override
public void onComplete() {
    ...
    if (!isCancelled()) {
        downstream.onComplete();          // ← only emits if not cancelled
    }
}

@Override
public void cancel() {
    cancelled = true;                     // ← records cancellation
    upstream.cancel();
}

return context.httpRequest();
}
return context.httpRequest().toBuilder()
.putHeader("Content-Length", String.valueOf(modifiedBytes.length))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GzipRequestInterceptor doesn't set Content-Length. AI says that SDK fills in Content-Length, but only when it's absent. So now in case of VectorSearch + compression Content-Length is wrong. Either all interceptors should set it or none.

@m-szymon

Copy link
Copy Markdown

Regarding conversions of FLOAT32VECTOR consider also some kind of compatibility switch in client.

Default: Keep the current behavior.
Server FLOAT32VECTOR -> interceptor -> DynamoDB L of N values
Applications can use: List<AttributeValue> values = item.get("embedding").l();

Opt-in: preserve mode
Expose server vectors as the existing magic-prefixed B attribute:
Server FLOAT32VECTOR -> interceptor -> magic-prefixed DynamoDB B
This is the same local representation created by: Float32Vector.toAttributeValue(0.25f, -1.5f, 3.0f)
It permits lossless read-modify-write:

Map<String, AttributeValue> item = client.getItem(request).item();
client.putItem(PutItemRequest.builder().tableName("copy").item(item).build());

In preserve mode, embedding.l() will not not work for optimized vectors.
Instead, Float32Vector should offer representation-independent accessors:

float[] values = Float32Vector.toFloats(item.get("embedding")); // decodes B-magic or converts List of Numbers
List<AttributeValue> numbers = Float32Vector.toNumberList(item.get("embedding")); // directly returns List of Numbers or converts B-magic

Both forms can be distinguished explicitly: boolean optimized = Float32Vector.isFloat32Vector(embedding);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants