3535import sqlite3
3636import sys
3737import hashlib
38+ import time
3839
3940# Increase recursion limit for deeply nested ASTs (gcc-mirror, llvm-project, boost)
4041sys .setrecursionlimit (50000 )
@@ -1299,7 +1300,9 @@ def _is_sane_compile_args(args: list[str]) -> bool:
12991300
13001301
13011302_SIMPLE_FALLBACK_ARGS = ["-fsyntax-only" , "-Wno-everything" ]
1302- DEFAULT_PARSE_BATCH_FILES = 100
1303+ DEFAULT_PARSE_BATCH_FILES = 25
1304+ PARSE_HEARTBEAT_FILES = 25
1305+ PARSE_HEARTBEAT_SECONDS = 30.0
13031306
13041307
13051308def compute_parse_batch_size (
@@ -1321,7 +1324,7 @@ def compute_parse_batch_size(
13211324 raise ValueError (f"effective_workers must be positive, got { effective_workers } " )
13221325 if max_batch_files <= 0 :
13231326 raise ValueError (f"max_batch_files must be positive, got { max_batch_files } " )
1324- nominal = max (50 , (num_files + effective_workers - 1 ) // effective_workers )
1327+ nominal = max (25 , (num_files + effective_workers - 1 ) // effective_workers )
13251328 return min (max_batch_files , nominal )
13261329
13271330
@@ -2885,14 +2888,27 @@ def _parse_file_batch(args_tuple):
28852888 func_results : list [dict ] = []
28862889 type_results : list [dict ] = []
28872890 errors = 0
2888- for filepath in filepaths :
2891+ last_heartbeat = time .monotonic ()
2892+ for idx , filepath in enumerate (filepaths , start = 1 ):
28892893 args = _resolve_file_args (filepath , compile_db , default_args )
28902894 try :
28912895 functions , typedefs = parse_translation_unit (filepath , clang_index , args , project_dir )
28922896 func_results .extend (f .to_dict () for f in functions )
28932897 type_results .extend (t .to_dict () for t in typedefs )
28942898 except (Exception , RecursionError ):
28952899 errors += 1
2900+ now = time .monotonic ()
2901+ if (
2902+ idx == len (filepaths )
2903+ or idx % PARSE_HEARTBEAT_FILES == 0
2904+ or now - last_heartbeat >= PARSE_HEARTBEAT_SECONDS
2905+ ):
2906+ print (
2907+ f" Parse worker heartbeat: { idx } /{ len (filepaths )} files" ,
2908+ file = sys .stderr ,
2909+ flush = True ,
2910+ )
2911+ last_heartbeat = now
28962912 return {"functions" : func_results , "typedefs" : type_results }, len (filepaths ), errors
28972913
28982914
@@ -3081,6 +3097,7 @@ def process_project(
30813097 clang_index = Index .create ()
30823098 parsed = 0
30833099 errors = 0
3100+ last_heartbeat = time .monotonic ()
30843101 for filepath in cpp_files :
30853102 args = _resolve_file_args (filepath , compile_db , default_args )
30863103 try :
@@ -3094,10 +3111,21 @@ def process_project(
30943111 errors += 1
30953112 if errors <= 5 :
30963113 print (f" ERROR parsing { filepath } : { e } " , file = sys .stderr )
3097- if parsed % 500 == 0 and parsed > 0 :
3114+ processed = parsed + errors
3115+ now = time .monotonic ()
3116+ if (
3117+ processed == len (cpp_files )
3118+ or (processed > 0 and processed % PARSE_HEARTBEAT_FILES == 0 )
3119+ or now - last_heartbeat >= PARSE_HEARTBEAT_SECONDS
3120+ ):
30983121 check_memory_limit (memory_limit_gb , label = "index_project" )
3099- print (f" Parsed { parsed } /{ len (cpp_files )} files, "
3100- f"{ len (index_obj .functions )} functions" , file = sys .stderr )
3122+ print (
3123+ f" Parsed { processed } /{ len (cpp_files )} files "
3124+ f"({ errors } errors), { len (index_obj .functions )} functions" ,
3125+ file = sys .stderr ,
3126+ flush = True ,
3127+ )
3128+ last_heartbeat = now
31013129 print (f" Parsed { parsed } files ({ errors } errors), "
31023130 f"{ len (index_obj .functions )} functions indexed" , file = sys .stderr )
31033131
0 commit comments