51
51
#include " indexer/LlvmAdapter.h"
52
52
#include " indexer/Logging.h"
53
53
#include " indexer/Path.h"
54
+ #include " indexer/ProgressReporter.h"
54
55
#include " indexer/RAII.h"
55
56
#include " indexer/ScipExtras.h"
56
57
#include " indexer/Statistics.h"
@@ -210,6 +211,7 @@ struct DriverOptions {
210
211
AbsolutePath statsFilePath;
211
212
AbsolutePath packageMapPath;
212
213
bool showCompilerDiagnostics;
214
+ bool showProgress;
213
215
DriverIpcOptions ipcOptions;
214
216
size_t numWorkers;
215
217
bool deterministic;
@@ -229,7 +231,8 @@ struct DriverOptions {
229
231
projectRootPath(AbsolutePath(" /" ), RootKind::Project), compdbPath(),
230
232
indexOutputPath(), statsFilePath(), packageMapPath(),
231
233
showCompilerDiagnostics(cliOpts.showCompilerDiagnostics),
232
- ipcOptions{cliOpts.ipcSizeHintBytes , cliOpts.receiveTimeout },
234
+ showProgress(cliOpts.showProgress), ipcOptions{cliOpts.ipcSizeHintBytes ,
235
+ cliOpts.receiveTimeout },
233
236
numWorkers (cliOpts.numWorkers), deterministic(cliOpts.deterministic),
234
237
preprocessorRecordHistoryFilterRegex (
235
238
cliOpts.preprocessorRecordHistoryFilterRegex),
@@ -336,6 +339,9 @@ struct DriverOptions {
336
339
if (this ->showCompilerDiagnostics ) {
337
340
args.push_back (" --show-compiler-diagnostics" );
338
341
}
342
+ if (!this ->showProgress ) {
343
+ args.push_back (" --no-progress-report" );
344
+ }
339
345
if (!this ->preprocessorRecordHistoryFilterRegex .empty ()) {
340
346
args.push_back (fmt::format (" --preprocessor-record-history-filter={}" ,
341
347
this ->preprocessorRecordHistoryFilterRegex ));
@@ -812,6 +818,13 @@ class Scheduler final {
812
818
return this ->maybeErroredJobs .size ();
813
819
}
814
820
821
+ std::string_view getTuPath (JobId jobId) const {
822
+ auto it = this ->allJobList .find (jobId);
823
+ ENFORCE (it != this ->allJobList .end ());
824
+ ENFORCE (it->second .job .kind == IndexJob::Kind::SemanticAnalysis);
825
+ return std::string_view (it->second .job .semanticAnalysis .command .filePath );
826
+ }
827
+
815
828
private:
816
829
ToBeScheduledWorkerId claimIdleWorker () {
817
830
ENFORCE (!this ->idleWorkers .empty ());
@@ -883,6 +896,7 @@ class Driver {
883
896
884
897
// / Total number of commands in the compilation database.
885
898
size_t compdbCommandCount = 0 ;
899
+ TusIndexedCount indexedSoFar;
886
900
compdb::ResumableParser compdbParser;
887
901
888
902
public:
@@ -1079,23 +1093,37 @@ class Driver {
1079
1093
llvm::UniqueStringSaver stringSaver{allocator};
1080
1094
scip::SymbolNameInterner interner{stringSaver};
1081
1095
scip::IndexBuilder builder{interner};
1082
- // TODO: Measure how much time this is taking and parallelize if too slow.
1083
- for (auto &paths : this ->shardPaths ) {
1084
- scip::Index indexShard;
1085
- if (!readIndexShard (paths.docsAndExternals , indexShard)) {
1086
- continue ;
1087
- }
1088
- for (auto &doc : *indexShard.mutable_documents ()) {
1089
- bool isMultiplyIndexed = this ->isMultiplyIndexedApproximate (
1090
- doc.relative_path (), paths.docsAndExternals .asRef (), badJobIds);
1091
- builder.addDocument (std::move (doc), isMultiplyIndexed);
1092
- }
1093
- // See NOTE(ref: precondition-deterministic-ext-symbol-docs); in
1094
- // deterministic mode, indexes should be the same, and iterated over in
1095
- // sorted order. So if external symbol emission in each part is
1096
- // deterministic, addExternalSymbol will be called in deterministic order.
1097
- for (auto &extSym : *indexShard.mutable_external_symbols ()) {
1098
- builder.addExternalSymbol (std::move (extSym));
1096
+ {
1097
+ ProgressReporter progressReporter (this ->options .showProgress ,
1098
+ " Merged partial index for" ,
1099
+ this ->shardPaths .size ());
1100
+ size_t count = 1 ;
1101
+ for (auto &paths : this ->shardPaths ) {
1102
+ scip::Index indexShard;
1103
+ if (!readIndexShard (paths.docsAndExternals , indexShard)) {
1104
+ continue ;
1105
+ }
1106
+ for (auto &doc : *indexShard.mutable_documents ()) {
1107
+ bool isMultiplyIndexed = this ->isMultiplyIndexedApproximate (
1108
+ doc.relative_path (), paths.docsAndExternals .asRef (), badJobIds);
1109
+ builder.addDocument (std::move (doc), isMultiplyIndexed);
1110
+ }
1111
+ // See NOTE(ref: precondition-deterministic-ext-symbol-docs); in
1112
+ // deterministic mode, indexes should be the same, and iterated over in
1113
+ // sorted order. So if external symbol emission in each part is
1114
+ // deterministic, addExternalSymbol will be called in deterministic
1115
+ // order.
1116
+ for (auto &extSym : *indexShard.mutable_external_symbols ()) {
1117
+ builder.addExternalSymbol (std::move (extSym));
1118
+ }
1119
+ if (auto optFileName = paths.docsAndExternals .asRef ().fileName ()) {
1120
+ if (auto optJobId = ShardPaths::tryParseJobId (optFileName.value ())) {
1121
+ progressReporter.report (
1122
+ count,
1123
+ this ->scheduler .getTuPath (JobId::newTask (optJobId.value ())));
1124
+ }
1125
+ }
1126
+ count++;
1099
1127
}
1100
1128
}
1101
1129
@@ -1178,19 +1206,20 @@ class Driver {
1178
1206
1179
1207
// / Returns the number of TUs processed
1180
1208
std::pair<TusIndexedCount, size_t > runJobsTillCompletionAndShutdownWorkers () {
1181
- TusIndexedCount tusIndexedCount{};
1209
+ ProgressReporter progressReporter (this ->options .showProgress , " Indexed" ,
1210
+ this ->compdbCommandCount );
1182
1211
this ->scheduler .runJobsTillCompletionAndShutdownWorkers (
1183
1212
Scheduler::RunCallbacks{
1184
- [this , &tusIndexedCount ]() -> void {
1185
- tusIndexedCount += this ->processOneOrMoreJobResults ();
1213
+ [this , &progressReporter ]() -> void {
1214
+ this ->processOneOrMoreJobResults (progressReporter );
1186
1215
},
1187
1216
[this ]() -> size_t { return this ->refillJobs (); },
1188
1217
[this ](ToBeScheduledWorkerId &&workerId, JobId jobId) -> bool {
1189
1218
return this ->tryAssignJobToWorker (std::move (workerId), jobId);
1190
1219
},
1191
1220
[this ](WorkerId workerId) { this ->shutdownWorker (workerId); }});
1192
1221
this ->scheduler .waitForAllWorkers ();
1193
- return {tusIndexedCount , this ->scheduler .numErroredJobs ()};
1222
+ return {this -> indexedSoFar , this ->scheduler .numErroredJobs ()};
1194
1223
}
1195
1224
1196
1225
FileGuard openCompilationDatabase () {
@@ -1241,17 +1270,17 @@ class Driver {
1241
1270
});
1242
1271
}
1243
1272
1244
- TusIndexedCount processWorkerResponse (IndexJobResponse &&response) {
1273
+ void processWorkerResponse (IndexJobResponse &&response,
1274
+ const ProgressReporter &progressReporter) {
1245
1275
TRACE_EVENT (tracing::indexing, " Driver::processWorkerResponse" ,
1246
1276
perfetto::TerminatingFlow::Global (response.jobId .traceId ()));
1247
- TusIndexedCount tusIndexedCount{};
1248
1277
auto optLatestIdleWorkerId = this ->scheduler .markCompleted (
1249
1278
response.workerId , response.jobId , response.result .kind );
1250
1279
if (!optLatestIdleWorkerId.has_value ()) {
1251
1280
spdlog::debug (" worker {} was terminated before job {}'s result "
1252
1281
" was processed, so can't send an emit index job" ,
1253
1282
response.workerId , response.jobId );
1254
- return tusIndexedCount ;
1283
+ return ;
1255
1284
}
1256
1285
auto latestIdleWorkerId = *optLatestIdleWorkerId;
1257
1286
switch (response.result .kind ) {
@@ -1299,7 +1328,7 @@ class Driver {
1299
1328
oldHandle.terminate ();
1300
1329
return this ->spawnWorker (workerId);
1301
1330
});
1302
- return tusIndexedCount ;
1331
+ return ;
1303
1332
}
1304
1333
break ;
1305
1334
}
@@ -1310,17 +1339,21 @@ class Driver {
1310
1339
std::move (result.statistics ));
1311
1340
}
1312
1341
this ->shardPaths .emplace_back (std::move (result.shardPaths ));
1313
- tusIndexedCount.value += 1 ;
1342
+ this ->indexedSoFar .value += 1 ;
1343
+ if (this ->options .showProgress ) {
1344
+ auto semaJobId = JobId::newTask (response.jobId .taskId ());
1345
+ progressReporter.report (this ->indexedSoFar .value ,
1346
+ this ->scheduler .getTuPath (semaJobId));
1347
+ }
1314
1348
break ;
1315
1349
}
1316
1350
}
1317
- return tusIndexedCount ;
1351
+ return ;
1318
1352
}
1319
1353
1320
- TusIndexedCount processOneOrMoreJobResults () {
1354
+ void processOneOrMoreJobResults (const ProgressReporter &progressReporter ) {
1321
1355
using namespace std ::chrono_literals;
1322
1356
auto workerTimeout = this ->receiveTimeout ();
1323
- TusIndexedCount tusIndexedCount{};
1324
1357
IndexJobResponse response;
1325
1358
TRACE_EVENT_BEGIN (tracing::ipc, " driver.waitForResponse" );
1326
1359
auto recvError =
@@ -1337,9 +1370,9 @@ class Driver {
1337
1370
} else {
1338
1371
spdlog::debug (" received response for {} from worker {}" , response.jobId ,
1339
1372
response.workerId );
1340
- tusIndexedCount = this ->processWorkerResponse (std::move (response));
1373
+ this ->processWorkerResponse (std::move (response), progressReporter );
1341
1374
while (this ->queues .workerToDriver .tryReceiveInstant (response)) {
1342
- tusIndexedCount += this ->processWorkerResponse (std::move (response));
1375
+ this ->processWorkerResponse (std::move (response), progressReporter );
1343
1376
}
1344
1377
}
1345
1378
// NOTE(def: mail-from-the-dead)
@@ -1360,7 +1393,7 @@ class Driver {
1360
1393
// was actually submitted by a worker which was terminated.
1361
1394
auto now = std::chrono::steady_clock::now ();
1362
1395
this ->terminateLongRunningWorkersAndRespawn (now - workerTimeout);
1363
- return tusIndexedCount ;
1396
+ return ;
1364
1397
}
1365
1398
1366
1399
// Assign a job to a specific worker. When this method is called,
0 commit comments