68
68
import org .opengrok .indexer .logger .LoggerFactory ;
69
69
import org .opengrok .indexer .util .ForbiddenSymlinkException ;
70
70
import org .opengrok .indexer .util .IOUtils ;
71
+ import org .opengrok .indexer .util .Progress ;
72
+ import org .opengrok .indexer .util .Statistics ;
71
73
import org .opengrok .indexer .util .TandemPath ;
72
74
73
75
/**
@@ -104,7 +106,7 @@ public boolean isHistoryIndexDone() {
104
106
* @param filename file path
105
107
* @param repository repository
106
108
* @param root root
107
- * @param tillRevision end revision
109
+ * @param tillRevision end revision (can be null)
108
110
*/
109
111
public void doRenamedFileHistory (String filename , File file , Repository repository , File root , String tillRevision )
110
112
throws HistoryException {
@@ -388,30 +390,8 @@ public void store(History history, Repository repository) throws HistoryExceptio
388
390
store (history , repository , null );
389
391
}
390
392
391
- /**
392
- * Store history for the whole repository in directory hierarchy resembling
393
- * the original repository structure. History of individual files will be
394
- * stored under this hierarchy, each file containing history of
395
- * corresponding source file.
396
- *
397
- * @param history history object to process into per-file histories
398
- * @param tillRevision end revision
399
- * @param repository repository object
400
- */
401
- @ Override
402
- public void store (History history , Repository repository , String tillRevision ) throws HistoryException {
403
-
404
- final boolean handleRenamedFiles = repository .isHandleRenamedFiles ();
405
-
393
+ private String createFileMap (History history , HashMap <String , List <HistoryEntry >> map ) {
406
394
String latestRev = null ;
407
-
408
- // Return immediately when there is nothing to do.
409
- List <HistoryEntry > entries = history .getHistoryEntries ();
410
- if (entries .isEmpty ()) {
411
- return ;
412
- }
413
-
414
- HashMap <String , List <HistoryEntry >> map = new HashMap <>();
415
395
HashMap <String , Boolean > acceptanceCache = new HashMap <>();
416
396
417
397
/*
@@ -455,6 +435,34 @@ public void store(History history, Repository repository, String tillRevision) t
455
435
list .add (e );
456
436
}
457
437
}
438
+ return latestRev ;
439
+ }
440
+
441
+ /**
442
+ * Store history for the whole repository in directory hierarchy resembling
443
+ * the original repository structure. History of individual files will be
444
+ * stored under this hierarchy, each file containing history of
445
+ * corresponding source file.
446
+ *
447
+ * @param history history object to process into per-file histories
448
+ * @param repository repository object
449
+ * @param tillRevision end revision (can be null)
450
+ */
451
+ @ Override
452
+ public void store (History history , Repository repository , String tillRevision ) throws HistoryException {
453
+
454
+ final boolean handleRenamedFiles = repository .isHandleRenamedFiles ();
455
+
456
+ String latestRev = null ;
457
+
458
+ // Return immediately when there is nothing to do.
459
+ List <HistoryEntry > entries = history .getHistoryEntries ();
460
+ if (entries .isEmpty ()) {
461
+ return ;
462
+ }
463
+
464
+ HashMap <String , List <HistoryEntry >> map = new HashMap <>();
465
+ latestRev = createFileMap (history , map );
458
466
459
467
// File based history cache does not store files for individual changesets so strip them.
460
468
history .strip ();
@@ -467,41 +475,46 @@ public void store(History history, Repository repository, String tillRevision) t
467
475
468
476
Set <String > regularFiles = map .keySet ().stream ().
469
477
filter (e -> !history .isRenamed (e )).collect (Collectors .toSet ());
470
- createDirectoriesForFiles (regularFiles );
478
+ createDirectoriesForFiles (regularFiles , repository , "regular files for history till " + tillRevision );
471
479
472
480
/*
473
481
* Now traverse the list of files from the hash map built above and for each file store its history
474
482
* (saved in the value of the hash map entry for the file) in a file.
475
483
* The renamed files will be handled separately.
476
484
*/
477
- LOGGER .log (Level .FINE , "Storing history for {0} regular files in repository ''{1}''" ,
478
- new Object []{regularFiles .size (), repository .getDirectoryName ()});
485
+ LOGGER .log (Level .FINE , "Storing history for {0} regular files in repository ''{1}'' till history {2} " ,
486
+ new Object []{regularFiles .size (), repository .getDirectoryName (), tillRevision });
479
487
final File root = env .getSourceRootFile ();
480
488
481
489
final CountDownLatch latch = new CountDownLatch (regularFiles .size ());
482
490
AtomicInteger fileHistoryCount = new AtomicInteger ();
483
- for (String file : regularFiles ) {
484
- env .getIndexerParallelizer ().getHistoryFileExecutor ().submit (() -> {
485
- try {
486
- doFileHistory (file , new History (map .get (file )), repository , root , false );
487
- fileHistoryCount .getAndIncrement ();
488
- } catch (Exception ex ) {
489
- // We want to catch any exception since we are in thread.
490
- LOGGER .log (Level .WARNING , "doFileHistory() got exception " , ex );
491
- } finally {
492
- latch .countDown ();
493
- }
494
- });
495
- }
491
+ try (Progress progress = new Progress (LOGGER ,
492
+ String .format ("history cache for regular files of %s till history %s" , repository , tillRevision ),
493
+ regularFiles .size ())) {
494
+ for (String file : regularFiles ) {
495
+ env .getIndexerParallelizer ().getHistoryFileExecutor ().submit (() -> {
496
+ try {
497
+ doFileHistory (file , new History (map .get (file )), repository , root , false );
498
+ fileHistoryCount .getAndIncrement ();
499
+ } catch (Exception ex ) {
500
+ // We want to catch any exception since we are in thread.
501
+ LOGGER .log (Level .WARNING , "doFileHistory() got exception " , ex );
502
+ } finally {
503
+ latch .countDown ();
504
+ progress .increment ();
505
+ }
506
+ });
507
+ }
496
508
497
- // Wait for the executors to finish.
498
- try {
499
- latch .await ();
500
- } catch (InterruptedException ex ) {
501
- LOGGER .log (Level .SEVERE , "latch exception" , ex );
509
+ // Wait for the executors to finish.
510
+ try {
511
+ latch .await ();
512
+ } catch (InterruptedException ex ) {
513
+ LOGGER .log (Level .SEVERE , "latch exception" , ex );
514
+ }
515
+ LOGGER .log (Level .FINE , "Stored history for {0} regular files in repository ''{1}''" ,
516
+ new Object []{fileHistoryCount , repository .getDirectoryName ()});
502
517
}
503
- LOGGER .log (Level .FINE , "Stored history for {0} regular files in repository ''{1}''" ,
504
- new Object []{fileHistoryCount , repository .getDirectoryName ()});
505
518
506
519
if (!handleRenamedFiles ) {
507
520
finishStore (repository , latestRev );
@@ -517,6 +530,7 @@ public void store(History history, Repository repository, String tillRevision) t
517
530
* handle renamed files (in parallel).
518
531
* @param renamedFiles set of renamed file paths
519
532
* @param repository repository
533
+ * @param tillRevision end revision (can be null)
520
534
*/
521
535
public void storeRenamed (Set <String > renamedFiles , Repository repository , String tillRevision ) throws HistoryException {
522
536
final File root = env .getSourceRootFile ();
@@ -526,47 +540,56 @@ public void storeRenamed(Set<String> renamedFiles, Repository repository, String
526
540
527
541
renamedFiles = renamedFiles .stream ().filter (f -> new File (env .getSourceRootPath () + f ).exists ()).
528
542
collect (Collectors .toSet ());
529
- LOGGER .log (Level .FINE , "Storing history for {0} renamed files in repository ''{1}''" ,
530
- new Object []{renamedFiles .size (), repository .getDirectoryName ()});
543
+ LOGGER .log (Level .FINE , "Storing history for {0} renamed files in repository ''{1}'' till history {2} " ,
544
+ new Object []{renamedFiles .size (), repository .getDirectoryName (), tillRevision });
531
545
532
- createDirectoriesForFiles (renamedFiles );
546
+ createDirectoriesForFiles (renamedFiles , repository , "renamed files for history till " + tillRevision );
533
547
534
548
final Repository repositoryF = repository ;
535
549
final CountDownLatch latch = new CountDownLatch (renamedFiles .size ());
536
550
AtomicInteger renamedFileHistoryCount = new AtomicInteger ();
537
- for (final String file : renamedFiles ) {
538
- env .getIndexerParallelizer ().getHistoryFileExecutor ().submit (() -> {
539
- try {
540
- doRenamedFileHistory (file ,
541
- new File (env .getSourceRootPath () + file ),
542
- repositoryF , root , tillRevision );
543
- renamedFileHistoryCount .getAndIncrement ();
544
- } catch (Exception ex ) {
545
- // We want to catch any exception since we are in thread.
546
- LOGGER .log (Level .WARNING ,
547
- "doFileHistory() got exception " , ex );
548
- } finally {
549
- latch .countDown ();
550
- }
551
- });
552
- }
551
+ try (Progress progress = new Progress (LOGGER ,
552
+ String .format ("history cache for renamed files of %s till history %s" , repository , tillRevision ),
553
+ renamedFiles .size ())) {
554
+ for (final String file : renamedFiles ) {
555
+ env .getIndexerParallelizer ().getHistoryFileExecutor ().submit (() -> {
556
+ try {
557
+ doRenamedFileHistory (file ,
558
+ new File (env .getSourceRootPath () + file ),
559
+ repositoryF , root , tillRevision );
560
+ renamedFileHistoryCount .getAndIncrement ();
561
+ } catch (Exception ex ) {
562
+ // We want to catch any exception since we are in thread.
563
+ LOGGER .log (Level .WARNING , "doFileHistory() got exception " , ex );
564
+ } finally {
565
+ latch .countDown ();
566
+ progress .increment ();
567
+ }
568
+ });
569
+ }
553
570
554
- // Wait for the executors to finish.
555
- try {
556
571
// Wait for the executors to finish.
557
- latch .await ();
558
- } catch (InterruptedException ex ) {
559
- LOGGER .log (Level .SEVERE , "latch exception" , ex );
572
+ try {
573
+ // Wait for the executors to finish.
574
+ latch .await ();
575
+ } catch (InterruptedException ex ) {
576
+ LOGGER .log (Level .SEVERE , "latch exception" , ex );
577
+ }
560
578
}
561
579
LOGGER .log (Level .FINE , "Stored history for {0} renamed files in repository ''{1}''" ,
562
580
new Object []{renamedFileHistoryCount .intValue (), repository .getDirectoryName ()});
563
581
}
564
582
565
- private void createDirectoriesForFiles (Set <String > files ) throws HistoryException {
583
+ private void createDirectoriesForFiles (Set <String > files , Repository repository , String label )
584
+ throws HistoryException {
585
+
566
586
// The directories for the files have to be created before
567
587
// the actual files otherwise storeFile() might be racing for
568
588
// mkdirs() if there are multiple files from single directory
569
589
// handled in parallel.
590
+ Statistics elapsed = new Statistics ();
591
+ LOGGER .log (Level .FINE , "Starting directory creation for {0} ({1}): {2} directories" ,
592
+ new Object []{repository , label , files .size ()});
570
593
for (final String file : files ) {
571
594
File cache ;
572
595
try {
@@ -578,10 +601,10 @@ private void createDirectoriesForFiles(Set<String> files) throws HistoryExceptio
578
601
File dir = cache .getParentFile ();
579
602
580
603
if (!dir .isDirectory () && !dir .mkdirs ()) {
581
- LOGGER .log (Level .WARNING ,
582
- "Unable to create cache directory ''{0}''." , dir );
604
+ LOGGER .log (Level .WARNING , "Unable to create cache directory ''{0}''." , dir );
583
605
}
584
606
}
607
+ elapsed .report (LOGGER , String .format ("Done creating directories for %s (%s)" , repository , label ));
585
608
}
586
609
587
610
@ Override
0 commit comments