66
77namespace CompactGUI . Core ;
88
9- public class Analyser
9+ public sealed class Analyser : IDisposable
1010{
1111
1212 public string FolderName { get ; set ; }
13- public long UncompressedBytes { get ; set ; }
14- public long CompressedBytes { get ; set ; }
15- public bool ContainsCompressedFiles { get ; set ; }
16- public List < AnalysedFileDetails > FileCompressionDetailsList { get ; set ; } = new List < AnalysedFileDetails > ( ) ;
17-
1813 private ILogger < Analyser > _logger ;
14+ private readonly FolderChangeMonitor _folderMonitor ;
15+ public bool HasFolderChanged => _folderMonitor . HasChanged ;
16+ public DateTime LastFolderChanged => _folderMonitor . LastChanged ;
17+
1918
2019 public Analyser ( string folder , ILogger < Analyser > logger )
2120 {
2221 FolderName = folder ;
23- UncompressedBytes = 0 ;
24- CompressedBytes = 0 ;
25- ContainsCompressedFiles = false ;
2622 _logger = logger ;
23+
24+ _folderMonitor = new FolderChangeMonitor ( folder ) ;
25+ _folderMonitor . Changed += ( s , e ) =>
26+ _logger . LogInformation ( "Folder change detected by FolderChangeMonitor for {FolderName}" , FolderName ) ;
27+ }
28+
29+
30+ public long CompressedBytes ;
31+ public long UncompressedBytes ;
32+ public bool ContainsCompressedFiles ;
33+
34+ private static long GetTotalCompressedBytes ( List < AnalysedFileDetails > fileCompressionDetailsList )
35+ {
36+ return fileCompressionDetailsList . Sum ( f => f . CompressedSize ) ;
37+ }
38+ private static long GetTotalUncompressedBytes ( List < AnalysedFileDetails > fileCompressionDetailsList )
39+ {
40+ return fileCompressionDetailsList . Sum ( f => f . UncompressedSize ) ;
41+ }
42+ private static bool GetContainsCompressedFiles ( List < AnalysedFileDetails > fileCompressionDetailsList )
43+ {
44+ return fileCompressionDetailsList . Any ( f => f . CompressionMode != WOFCompressionAlgorithm . NO_COMPRESSION ) ;
45+ }
46+
47+
48+ private List < AnalysedFileDetails > ? _analysedFileDetails ;
49+
50+ public async ValueTask < List < AnalysedFileDetails > ? > GetAnalysedFilesAsync ( CancellationToken token )
51+ {
52+ if ( _analysedFileDetails != null && ! HasFolderChanged )
53+ {
54+ _logger . LogInformation ( "Returning cached analysed files for folder {FolderName}" , FolderName ) ;
55+ return _analysedFileDetails ;
56+ }
57+
58+ _logger . LogInformation ( "Analysing folder {FolderName} for the first time or after a change" , FolderName ) ;
59+ _analysedFileDetails = await AnalyseFolder ( token ) . ConfigureAwait ( false ) ;
60+ return _analysedFileDetails ;
2761 }
2862
2963
30- public async Task < Boolean ? > AnalyseFolder ( CancellationToken cancellationToken )
64+ private async Task < List < AnalysedFileDetails > ? > AnalyseFolder ( CancellationToken cancellationToken )
3165 {
66+
67+ List < AnalysedFileDetails > ? AnalysedFileDetails ;
68+
3269 AnalyserLog . StartingAnalysis ( _logger , FolderName ) ;
3370 Stopwatch sw = Stopwatch . StartNew ( ) ;
3471 try
@@ -41,11 +78,7 @@ public Analyser(string folder, ILogger<Analyser> logger)
4178 . OfType < AnalysedFileDetails > ( )
4279 . ToList ( ) ;
4380
44- CompressedBytes = fileDetails . Sum ( f => f . CompressedSize ) ;
45- UncompressedBytes = fileDetails . Sum ( f => f . UncompressedSize ) ;
46- ContainsCompressedFiles = fileDetails . Any ( f => f . CompressionMode != WOFCompressionAlgorithm . NO_COMPRESSION ) ;
47-
48- FileCompressionDetailsList = fileDetails ;
81+ AnalysedFileDetails = fileDetails ;
4982 }
5083 catch ( Exception ex )
5184 {
@@ -54,9 +87,14 @@ public Analyser(string folder, ILogger<Analyser> logger)
5487 }
5588 finally { sw . Stop ( ) ; }
5689
90+ _folderMonitor . Reset ( ) ;
91+
92+ CompressedBytes = GetTotalCompressedBytes ( AnalysedFileDetails ) ;
93+ UncompressedBytes = GetTotalUncompressedBytes ( AnalysedFileDetails ) ;
94+ ContainsCompressedFiles = GetContainsCompressedFiles ( AnalysedFileDetails ) ;
5795 AnalyserLog . AnalysisCompleted ( _logger , FolderName , Math . Round ( sw . Elapsed . TotalSeconds , 3 ) , CompressedBytes , UncompressedBytes , ContainsCompressedFiles ) ;
5896
59- return ContainsCompressedFiles ;
97+ return AnalysedFileDetails ;
6098
6199
62100 }
@@ -88,9 +126,9 @@ public Analyser(string folder, ILogger<Analyser> logger)
88126 public List < ExtensionResult > GetPoorlyCompressedExtensions ( )
89127 {
90128 // Only use PLINQ if the list is large enough to benefit from parallel processing
91- IEnumerable < AnalysedFileDetails > query = FileCompressionDetailsList . Count <= 10000
92- ? FileCompressionDetailsList
93- : FileCompressionDetailsList . AsParallel ( ) ;
129+ IEnumerable < AnalysedFileDetails > query = _analysedFileDetails ? . Count <= 10000
130+ ? _analysedFileDetails
131+ : _analysedFileDetails . AsParallel ( ) ;
94132
95133 return query
96134 . Where ( fl => fl . UncompressedSize > 0 )
@@ -107,6 +145,11 @@ public List<ExtensionResult> GetPoorlyCompressedExtensions()
107145
108146 }
109147
148+ public void Dispose ( )
149+ {
150+ _folderMonitor . Dispose ( ) ;
151+ _analysedFileDetails ? . Clear ( ) ;
152+ }
110153}
111154
112155
0 commit comments