From d1f7ae8fa7a2d9be0fcdcc2c9810c779dc90f822 Mon Sep 17 00:00:00 2001 From: AJ Roetker Date: Wed, 19 Aug 2026 11:24:15 -0700 Subject: [PATCH 1/3] Isolate Antfly vector benchmark indexing --- tests/test_antfly.py | 33 +++++++++++++-- .../backend/clients/antfly/antfly.py | 40 +++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/tests/test_antfly.py b/tests/test_antfly.py index 024a3b14f..fae188792 100644 --- a/tests/test_antfly.py +++ b/tests/test_antfly.py @@ -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 @@ -105,3 +106,29 @@ 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" + ] diff --git a/vectordb_bench/backend/clients/antfly/antfly.py b/vectordb_bench/backend/clients/antfly/antfly.py index be9a99c5b..46b163505 100644 --- a/vectordb_bench/backend/clients/antfly/antfly.py +++ b/vectordb_bench/backend/clients/antfly/antfly.py @@ -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" @@ -128,6 +129,16 @@ 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. + keep_default_full_text = os.environ.get( + "ANTFLY_VDBBENCH_KEEP_DEFAULT_FULL_TEXT", "" + ).lower() in {"1", "true", "yes"} + if not keep_default_full_text: + 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 @@ -137,6 +148,35 @@ def __init__( finally: client.close() + def _remove_default_full_text_index(self, client: httpx.Client) -> None: + path = ( + f"/tables/{self.collection_name}/indexes/" + f"{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) + raise TimeoutError( + "Antfly default full-text index removal did not become visible " + f"within {TABLE_READY_TIMEOUT}s" + ) + def _ensure_external_index(self, client: httpx.Client, dim: int) -> None: """Create the external embeddings index, verifying shard registration. From ea666ede1fae37b661fe311801ab8e955598666d Mon Sep 17 00:00:00 2001 From: AJ Roetker Date: Wed, 19 Aug 2026 11:35:14 -0700 Subject: [PATCH 2/3] Format and test full-text benchmark opt-in --- tests/test_antfly.py | 13 +++++++++--- .../backend/clients/antfly/antfly.py | 20 +++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/tests/test_antfly.py b/tests/test_antfly.py index fae188792..cfc34bd8e 100644 --- a/tests/test_antfly.py +++ b/tests/test_antfly.py @@ -129,6 +129,13 @@ def delete(self, path: str): adapter._remove_default_full_text_index(client) - assert client.deleted == [ - "/tables/vdbbench/indexes/full_text_index_v0" - ] + 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 diff --git a/vectordb_bench/backend/clients/antfly/antfly.py b/vectordb_bench/backend/clients/antfly/antfly.py index 46b163505..bca2f83d1 100644 --- a/vectordb_bench/backend/clients/antfly/antfly.py +++ b/vectordb_bench/backend/clients/antfly/antfly.py @@ -133,10 +133,7 @@ def __init__( # 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. - keep_default_full_text = os.environ.get( - "ANTFLY_VDBBENCH_KEEP_DEFAULT_FULL_TEXT", "" - ).lower() in {"1", "true", "yes"} - if not keep_default_full_text: + if not self._keep_default_full_text_index(): self._remove_default_full_text_index(client) self._ensure_external_index(client, dim) @@ -149,19 +146,14 @@ def __init__( client.close() def _remove_default_full_text_index(self, client: httpx.Client) -> None: - path = ( - f"/tables/{self.collection_name}/indexes/" - f"{DEFAULT_FULL_TEXT_INDEX_NAME}" - ) + 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 - ) + log.info("Remove default full-text index response: %s", response.status_code) if response.status_code != 404: response.raise_for_status() @@ -173,10 +165,12 @@ def _remove_default_full_text_index(self, client: httpx.Client) -> None: probe.raise_for_status() time.sleep(TABLE_READY_POLL_INTERVAL) raise TimeoutError( - "Antfly default full-text index removal did not become visible " - f"within {TABLE_READY_TIMEOUT}s" + "Antfly default full-text index removal did not become visible " f"within {TABLE_READY_TIMEOUT}s" ) + 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. From 885fdfb1858a2cad6424598a6b8223e5d8bc8a94 Mon Sep 17 00:00:00 2001 From: AJ Roetker Date: Wed, 19 Aug 2026 11:37:52 -0700 Subject: [PATCH 3/3] Satisfy Antfly adapter lint --- vectordb_bench/backend/clients/antfly/antfly.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vectordb_bench/backend/clients/antfly/antfly.py b/vectordb_bench/backend/clients/antfly/antfly.py index bca2f83d1..aa26201a9 100644 --- a/vectordb_bench/backend/clients/antfly/antfly.py +++ b/vectordb_bench/backend/clients/antfly/antfly.py @@ -164,9 +164,8 @@ def _remove_default_full_text_index(self, client: httpx.Client) -> None: return probe.raise_for_status() time.sleep(TABLE_READY_POLL_INTERVAL) - raise TimeoutError( - "Antfly default full-text index removal did not become visible " f"within {TABLE_READY_TIMEOUT}s" - ) + 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"}