@@ -245,13 +245,19 @@ static History readCache(File file) throws IOException {
245
245
* @param cacheFile the file to store the history to
246
246
*/
247
247
private void writeHistoryToFile (File dir , History history , File cacheFile ) throws HistoryException {
248
+
249
+ if (LOGGER .isLoggable (Level .FINEST )) {
250
+ LOGGER .log (Level .FINEST , "writing history entries to ''{0}'': {1}" ,
251
+ new Object []{cacheFile , history .getRevisionList ()});
252
+ }
253
+
248
254
// We have a problem that multiple threads may access the cache layer
249
255
// at the same time. Since I would like to avoid read-locking, I just
250
256
// serialize the write access to the cache file. The generation of the
251
257
// cache file would most likely be executed during index generation, and
252
- // that happens sequencial anyway....
258
+ // that happens sequential anyway....
253
259
// Generate the file with a temporary name and move it into place when
254
- // I'm done so I don't have to protect the readers for partially updated
260
+ // done, so it is not necessary to protect the readers for partially updated
255
261
// files...
256
262
final File output ;
257
263
try {
@@ -305,19 +311,23 @@ private History mergeOldAndNewHistory(File cacheFile, History histNew, Repositor
305
311
// Merge old history with the new history.
306
312
List <HistoryEntry > listOld = histOld .getHistoryEntries ();
307
313
if (!listOld .isEmpty ()) {
314
+ if (LOGGER .isLoggable (Level .FINEST )) {
315
+ LOGGER .log (Level .FINEST , "for ''{0}'' merging old history {1} with new history {2}" ,
316
+ new Object []{cacheFile , histOld .getRevisionList (), histNew .getRevisionList ()});
317
+ }
308
318
List <HistoryEntry > listNew = histNew .getHistoryEntries ();
309
319
ListIterator <HistoryEntry > li = listNew .listIterator (listNew .size ());
310
320
while (li .hasPrevious ()) {
311
321
listOld .add (0 , li .previous ());
312
322
}
313
323
history = new History (listOld );
314
324
315
- // Retag the changesets in case there have been some new
325
+ // Re-tag the changesets in case there have been some new
316
326
// tags added to the repository. Technically we should just
317
- // retag the last revision from the listOld however this
327
+ // re-tag the last revision from the listOld however this
318
328
// does not solve the problem when listNew contains new tags
319
- // retroactively tagging changesets from listOld so we resort
320
- // to this somewhat crude solution of retagging from scratch.
329
+ // retroactively tagging changesets from listOld, so we resort
330
+ // to this somewhat crude solution of re-tagging from scratch.
321
331
if (env .isTagsEnabled () && repo .hasFileBasedTags ()) {
322
332
history .strip ();
323
333
repo .assignTagsInHistory (history );
@@ -361,16 +371,16 @@ private void storeFile(History histNew, File file, Repository repo, boolean merg
361
371
}
362
372
363
373
// If the merge failed, null history will be returned.
364
- // In such case store at least new history as a best effort.
374
+ // In such case store at least new history as the best effort.
365
375
if (history == null ) {
376
+ LOGGER .log (Level .WARNING , "history cache for file ''{0}'' truncated to new history" , file );
366
377
history = histNew ;
367
378
}
368
379
369
380
writeHistoryToFile (dir , history , cacheFile );
370
381
}
371
382
372
- private void storeFile (History histNew , File file , Repository repo )
373
- throws HistoryException {
383
+ private void storeFile (History histNew , File file , Repository repo ) throws HistoryException {
374
384
storeFile (histNew , file , repo , false );
375
385
}
376
386
@@ -382,7 +392,7 @@ private void finishStore(Repository repository, String latestRev) {
382
392
// create confusion (once it starts working again).
383
393
LOGGER .log (Level .WARNING ,
384
394
"Could not store history for repository {0}: {1} is not a directory" ,
385
- new Object []{repository . getDirectoryName () , histDir });
395
+ new Object []{repository , histDir });
386
396
} else {
387
397
storeLatestCachedRevision (repository , latestRev );
388
398
}
@@ -495,7 +505,7 @@ public void store(History history, Repository repository, String tillRevision) t
495
505
* The renamed files will be handled separately.
496
506
*/
497
507
LOGGER .log (Level .FINE , "Storing history for {0} regular files in repository ''{1}'' till {2}" ,
498
- new Object []{regularFiles .size (), repository . getDirectoryName () , getRevisionString (tillRevision )});
508
+ new Object []{regularFiles .size (), repository , getRevisionString (tillRevision )});
499
509
final File root = env .getSourceRootFile ();
500
510
501
511
final CountDownLatch latch = new CountDownLatch (regularFiles .size ());
@@ -526,7 +536,7 @@ public void store(History history, Repository repository, String tillRevision) t
526
536
LOGGER .log (Level .SEVERE , "latch exception" , ex );
527
537
}
528
538
LOGGER .log (Level .FINE , "Stored history for {0} regular files in repository ''{1}''" ,
529
- new Object []{fileHistoryCount , repository . getDirectoryName () });
539
+ new Object []{fileHistoryCount , repository });
530
540
}
531
541
532
542
if (!handleRenamedFiles ) {
@@ -554,7 +564,7 @@ public void storeRenamed(Set<String> renamedFiles, Repository repository, String
554
564
renamedFiles = renamedFiles .stream ().filter (f -> new File (env .getSourceRootPath () + f ).exists ()).
555
565
collect (Collectors .toSet ());
556
566
LOGGER .log (Level .FINE , "Storing history for {0} renamed files in repository ''{1}'' till {2}" ,
557
- new Object []{renamedFiles .size (), repository . getDirectoryName () , getRevisionString (tillRevision )});
567
+ new Object []{renamedFiles .size (), repository , getRevisionString (tillRevision )});
558
568
559
569
createDirectoriesForFiles (renamedFiles , repository , "renamed files for history " +
560
570
getRevisionString (tillRevision ));
@@ -592,7 +602,7 @@ public void storeRenamed(Set<String> renamedFiles, Repository repository, String
592
602
}
593
603
}
594
604
LOGGER .log (Level .FINE , "Stored history for {0} renamed files in repository ''{1}''" ,
595
- new Object []{renamedFileHistoryCount .intValue (), repository . getDirectoryName () });
605
+ new Object []{renamedFileHistoryCount .intValue (), repository });
596
606
}
597
607
598
608
private void createDirectoriesForFiles (Set <String > files , Repository repository , String label )
@@ -625,22 +635,22 @@ private void createDirectoriesForFiles(Set<String> files, Repository repository,
625
635
@ Override
626
636
public History get (File file , Repository repository , boolean withFiles )
627
637
throws HistoryException , ForbiddenSymlinkException {
628
- File cache = getCachedFile (file );
629
- if (isUpToDate (file , cache )) {
638
+ File cacheFile = getCachedFile (file );
639
+ if (isUpToDate (file , cacheFile )) {
630
640
try {
631
641
if (fileHistoryCacheHits != null ) {
632
642
fileHistoryCacheHits .increment ();
633
643
}
634
- return readCache (cache );
644
+ return readCache (cacheFile );
635
645
} catch (Exception e ) {
636
- LOGGER .log (Level .WARNING ,
637
- "Error when reading cache file '" + cache , e );
646
+ LOGGER .log (Level .WARNING , String .format ("Error when reading cache file '%s'" , cacheFile ), e );
638
647
}
639
648
}
640
649
641
650
if (fileHistoryCacheMisses != null ) {
642
651
fileHistoryCacheMisses .increment ();
643
652
}
653
+
644
654
/*
645
655
* Some mirrors of repositories which are capable of fetching history
646
656
* for directories may contain lots of files untracked by given SCM.
@@ -666,21 +676,28 @@ public History get(File file, Repository repository, boolean withFiles)
666
676
time = System .currentTimeMillis () - time ;
667
677
} catch (UnsupportedOperationException e ) {
668
678
// In this case, we've found a file for which the SCM has no history
669
- // An example is a non-SCCS file somewhere in an SCCS-controlled
670
- // workspace.
679
+ // An example is a non-SCCS file somewhere in an SCCS-controlled workspace.
671
680
return null ;
672
681
}
673
682
683
+ // Don't cache history-information for directories, since the
684
+ // history information on the directory may change if a file in
685
+ // a sub-directory change. This will cause us to present a stale
686
+ // history log until the current directory is updated and
687
+ // invalidates the cache entry.
674
688
if (!file .isDirectory ()) {
675
- // Don't cache history-information for directories, since the
676
- // history information on the directory may change if a file in
677
- // a sub-directory change. This will cause us to present a stale
678
- // history log until a the current directory is updated and
679
- // invalidates the cache entry.
680
- if ((cache != null ) &&
681
- (cache .exists () ||
682
- (time > env .getHistoryReaderTimeLimit ()))) {
683
- // retrieving the history takes too long, cache it!
689
+ // Either the cache is stale or retrieving the history took too long, cache it!
690
+ if (cacheFile .exists ()) {
691
+ if (LOGGER .isLoggable (Level .FINEST )) {
692
+ LOGGER .log (Level .FINEST , "refreshing history for ''{0}'': {1}" ,
693
+ new Object []{file , history .getRevisionList ()});
694
+ }
695
+ storeFile (history , file , repository );
696
+ } else if (time > env .getHistoryReaderTimeLimit ()) {
697
+ if (LOGGER .isLoggable (Level .FINEST )) {
698
+ LOGGER .log (Level .FINEST , "getting history for ''{0}'' took longer than {1} ms, caching it: {2}" ,
699
+ new Object []{file , env .getHistoryReaderTimeLimit (), history .getRevisionList ()});
700
+ }
684
701
storeFile (history , file , repository );
685
702
}
686
703
}
@@ -714,11 +731,10 @@ public String getRepositoryHistDataDirname(Repository repository) {
714
731
String repoDirBasename ;
715
732
716
733
try {
717
- repoDirBasename = env .getPathRelativeToSourceRoot (
718
- new File (repository .getDirectoryName ()));
734
+ repoDirBasename = env .getPathRelativeToSourceRoot (new File (repository .getDirectoryName ()));
719
735
} catch (IOException ex ) {
720
- LOGGER .log (Level .WARNING , "Could not resolve " +
721
- repository . getDirectoryName () + " relative to source root" , ex );
736
+ LOGGER .log (Level .WARNING ,
737
+ String . format ( "Could not resolve repository %s relative to source root", repository ) , ex );
722
738
return null ;
723
739
} catch (ForbiddenSymlinkException ex ) {
724
740
LOGGER .log (Level .FINER , ex .getMessage ());
@@ -751,8 +767,8 @@ private void storeLatestCachedRevision(Repository repository, String rev) {
751
767
new FileOutputStream (getRepositoryCachedRevPath (repository ))));
752
768
writer .write (rev );
753
769
} catch (IOException ex ) {
754
- LOGGER .log (Level .WARNING , "Cannot write latest cached revision to file for " + repository . getDirectoryName (),
755
- ex );
770
+ LOGGER .log (Level .WARNING ,
771
+ String . format ( "Cannot write latest cached revision to file for repository %s" , repository ), ex );
756
772
} finally {
757
773
try {
758
774
if (writer != null ) {
@@ -771,8 +787,7 @@ public String getLatestCachedRevision(Repository repository) {
771
787
772
788
String revPath = getRepositoryCachedRevPath (repository );
773
789
if (revPath == null ) {
774
- LOGGER .log (Level .WARNING , "no rev path for {0}" ,
775
- repository .getDirectoryName ());
790
+ LOGGER .log (Level .WARNING , "no rev path for repository {0}" , repository );
776
791
return null ;
777
792
}
778
793
0 commit comments