Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions tests/test_antfly.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ def search_param(self):


class _Response:
is_success = True
status_code = 200
text = ""
def __init__(self, status_code: int = 200):
self.status_code = status_code
self.is_success = 200 <= status_code < 300
self.text = ""

def raise_for_status(self):
return None
Expand Down Expand Up @@ -105,3 +106,36 @@ def test_write_readiness_probe_does_not_create_a_tombstone():
"inserts": {"key:__circus_write_probe__": {"id": -1}},
"sync_level": "write",
}


def test_vector_benchmark_removes_default_full_text_index(monkeypatch):
adapter = _adapter()

class Client:
def __init__(self):
self.present = True
self.deleted = []

def get(self, path: str):
return _Response(200 if self.present else 404)

def delete(self, path: str):
self.deleted.append(path)
self.present = False
return _Response(204)

client = Client()
monkeypatch.setattr("time.sleep", lambda _: None)

adapter._remove_default_full_text_index(client)

assert client.deleted == ["/tables/vdbbench/indexes/full_text_index_v0"]


def test_vector_benchmark_can_keep_default_full_text_index(monkeypatch):
adapter = _adapter()

monkeypatch.delenv("ANTFLY_VDBBENCH_KEEP_DEFAULT_FULL_TEXT", raising=False)
assert adapter._keep_default_full_text_index() is False
monkeypatch.setenv("ANTFLY_VDBBENCH_KEEP_DEFAULT_FULL_TEXT", "yes")
assert adapter._keep_default_full_text_index() is True
33 changes: 33 additions & 0 deletions vectordb_bench/backend/clients/antfly/antfly.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
INDEX_READY_POLL_INTERVAL = 2
INDEX_NAME = "vec"
INDEX_TYPES = ("embeddings", "aknn_v0")
DEFAULT_FULL_TEXT_INDEX_NAME = "full_text_index_v0"
SOURCE_FIELD = "vec_data"


Expand Down Expand Up @@ -128,6 +129,13 @@ def __init__(
# while the shard is still initializing.
self._wait_for_write_ready(client)

# Antfly's table quickstart contract creates a default full-text
# index even when the caller supplies no indexes. VectorDBBench is
# an ANN benchmark, so remove that unrelated replay consumer before
# loading unless a diagnostic run explicitly asks to retain it.
if not self._keep_default_full_text_index():
self._remove_default_full_text_index(client)

self._ensure_external_index(client, dim)
# Do not wait for an empty external index to finish rebuilding here.
# antfly-zig keeps an empty external dense index in backfill state
Expand All @@ -137,6 +145,31 @@ def __init__(
finally:
client.close()

def _remove_default_full_text_index(self, client: httpx.Client) -> None:
path = f"/tables/{self.collection_name}/indexes/{DEFAULT_FULL_TEXT_INDEX_NAME}"
existing = client.get(path)
if existing.status_code == 404:
return
existing.raise_for_status()

response = client.delete(path)
log.info("Remove default full-text index response: %s", response.status_code)
if response.status_code != 404:
response.raise_for_status()

deadline = time.monotonic() + TABLE_READY_TIMEOUT
while time.monotonic() < deadline:
probe = client.get(path)
if probe.status_code == 404:
return
probe.raise_for_status()
time.sleep(TABLE_READY_POLL_INTERVAL)
message = f"Antfly default full-text index removal did not become visible within {TABLE_READY_TIMEOUT}s"
raise TimeoutError(message)

def _keep_default_full_text_index(self) -> bool:
return os.environ.get("ANTFLY_VDBBENCH_KEEP_DEFAULT_FULL_TEXT", "").lower() in {"1", "true", "yes"}

def _ensure_external_index(self, client: httpx.Client, dim: int) -> None:
"""Create the external embeddings index, verifying shard registration.

Expand Down
Loading