Skip to content

Commit d8f6ca4

Browse files
committed
Process parse batches as they complete
1 parent dec1457 commit d8f6ca4

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

tests/test_index_project_parse_batch.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
from concurrent.futures import Future
34
import sys
45
from pathlib import Path
56

@@ -31,3 +32,26 @@ def test_parse_batch_size_rejects_invalid_worker_count():
3132

3233
with pytest.raises(ValueError):
3334
index_project.compute_parse_batch_size(100, 0)
35+
36+
37+
def test_parse_batch_results_follow_completion_order(monkeypatch):
38+
import index_project
39+
40+
submitted: list[Future] = []
41+
42+
class FakeExecutor:
43+
def submit(self, _fn, batch):
44+
future: Future = Future()
45+
future.set_result(batch)
46+
submitted.append(future)
47+
return future
48+
49+
def fake_as_completed(futures):
50+
assert list(futures) == submitted
51+
return reversed(submitted)
52+
53+
monkeypatch.setattr(index_project, "as_completed", fake_as_completed)
54+
55+
results = list(index_project._iter_parse_batch_results(FakeExecutor(), ["slow", "fast"]))
56+
57+
assert results == ["fast", "slow"]

tools/clang_indexer/index_project.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2896,6 +2896,13 @@ def _parse_file_batch(args_tuple):
28962896
return {"functions": func_results, "typedefs": type_results}, len(filepaths), errors
28972897

28982898

2899+
def _iter_parse_batch_results(executor, batches):
2900+
"""Yield parse batch results as workers finish, not in submit order."""
2901+
futures = [executor.submit(_parse_file_batch, batch) for batch in batches]
2902+
for future in as_completed(futures):
2903+
yield future.result()
2904+
2905+
28992906
def _parse_single_file_worker(args_tuple):
29002907
"""Parse one file in a fresh subprocess so a segfault is file-local."""
29012908
filepath, compile_db, default_args, project_dir = args_tuple
@@ -3039,7 +3046,10 @@ def process_project(
30393046
total_errors = 0
30403047
try:
30413048
with ProcessPoolExecutor(max_workers=effective_workers) as executor:
3042-
for payload, parsed_count, error_count in executor.map(_parse_file_batch, batches):
3049+
for payload, parsed_count, error_count in _iter_parse_batch_results(
3050+
executor,
3051+
batches,
3052+
):
30433053
for d in payload["functions"]:
30443054
index_obj.add_function(FunctionDef.from_dict(d))
30453055
for td in payload["typedefs"]:

0 commit comments

Comments
 (0)