@@ -75,12 +75,18 @@ export function activateExtension(context: vscode.ExtensionContext, magentoRoot:
75
75
const reportPath = path . join ( magentoRoot , 'var' , 'report' ) ;
76
76
77
77
const logWatcher = vscode . workspace . createFileSystemWatcher ( new vscode . RelativePattern ( logPath , '*' ) ) ;
78
- logWatcher . onDidChange ( ( ) => logViewerProvider . refresh ( ) ) ;
78
+ logWatcher . onDidChange ( ( uri ) => {
79
+ invalidateFileCache ( uri . fsPath ) ;
80
+ logViewerProvider . refresh ( ) ;
81
+ } ) ;
79
82
logWatcher . onDidCreate ( ( ) => logViewerProvider . refresh ( ) ) ;
80
83
logWatcher . onDidDelete ( ( ) => logViewerProvider . refresh ( ) ) ;
81
84
82
85
const reportWatcher = vscode . workspace . createFileSystemWatcher ( new vscode . RelativePattern ( reportPath , '*' ) ) ;
83
- reportWatcher . onDidChange ( ( ) => reportViewerProvider . refresh ( ) ) ;
86
+ reportWatcher . onDidChange ( ( uri ) => {
87
+ invalidateFileCache ( uri . fsPath ) ;
88
+ reportViewerProvider . refresh ( ) ;
89
+ } ) ;
84
90
reportWatcher . onDidCreate ( ( ) => reportViewerProvider . refresh ( ) ) ;
85
91
reportWatcher . onDidDelete ( ( ) => reportViewerProvider . refresh ( ) ) ;
86
92
@@ -181,23 +187,6 @@ export function deleteReportFile(filePath: string): void {
181
187
}
182
188
}
183
189
184
- // Clears all report files in the Magento report directory.
185
- export function clearAllReportFiles ( reportViewerProvider : ReportViewerProvider , magentoRoot : string ) : void {
186
- vscode . window . showWarningMessage ( 'Are you sure you want to delete all report files?' , 'Yes' , 'No' ) . then ( selection => {
187
- if ( selection === 'Yes' ) {
188
- const reportPath = path . join ( magentoRoot , 'var' , 'report' ) ;
189
- if ( pathExists ( reportPath ) ) {
190
- const files = fs . readdirSync ( reportPath ) ;
191
- files . forEach ( file => fs . unlinkSync ( path . join ( reportPath , file ) ) ) ;
192
- reportViewerProvider . refresh ( ) ;
193
- showInformationMessage ( 'All report files have been cleared.' ) ;
194
- } else {
195
- showInformationMessage ( 'No report files found to clear.' ) ;
196
- }
197
- }
198
- } ) ;
199
- }
200
-
201
190
// Cache for badge updates
202
191
let lastUpdateTime = 0 ;
203
192
const BADGE_UPDATE_THROTTLE = 1000 ; // Maximum one update per second
@@ -363,8 +352,12 @@ export function getLineCount(filePath: string): number {
363
352
364
353
return estimatedLines ;
365
354
} else {
366
- // For smaller files, we read them completely
367
- const fileContent = fs . readFileSync ( filePath , 'utf-8' ) ;
355
+ // For smaller files, use cached content
356
+ const fileContent = getCachedFileContent ( filePath ) ;
357
+ if ( ! fileContent ) {
358
+ return 0 ;
359
+ }
360
+
368
361
const lineCount = fileContent . split ( '\n' ) . length ;
369
362
370
363
lineCountCache . set ( filePath , {
@@ -430,6 +423,11 @@ export function getLogItems(dir: string, parseTitle: (filePath: string) => strin
430
423
// Cache for JSON reports to avoid repeated parsing
431
424
const reportCache = new Map < string , { content : unknown , timestamp : number } > ( ) ;
432
425
426
+ // Cache for file contents to avoid repeated reads
427
+ const fileContentCache = new Map < string , { content : string , timestamp : number } > ( ) ;
428
+ const FILE_CACHE_MAX_SIZE = 50 ; // Maximum number of files to cache
429
+ const FILE_CACHE_MAX_FILE_SIZE = 5 * 1024 * 1024 ; // 5MB max file size for caching
430
+
433
431
// Helper function for reading and parsing JSON reports with caching
434
432
function getReportContent ( filePath : string ) : unknown | null {
435
433
try {
@@ -440,7 +438,11 @@ function getReportContent(filePath: string): unknown | null {
440
438
return cachedReport . content ;
441
439
}
442
440
443
- const fileContent = fs . readFileSync ( filePath , 'utf-8' ) ;
441
+ const fileContent = getCachedFileContent ( filePath ) ;
442
+ if ( ! fileContent ) {
443
+ return null ;
444
+ }
445
+
444
446
const report = JSON . parse ( fileContent ) ;
445
447
446
448
reportCache . set ( filePath , {
@@ -454,6 +456,64 @@ function getReportContent(filePath: string): unknown | null {
454
456
}
455
457
}
456
458
459
+ // Enhanced file content caching function
460
+ export function getCachedFileContent ( filePath : string ) : string | null {
461
+ try {
462
+ // Check if file exists first
463
+ if ( ! fs . existsSync ( filePath ) ) {
464
+ return null ;
465
+ }
466
+
467
+ const stats = fs . statSync ( filePath ) ;
468
+
469
+ // Don't cache files larger than 5MB to prevent memory issues
470
+ if ( stats . size > FILE_CACHE_MAX_FILE_SIZE ) {
471
+ return fs . readFileSync ( filePath , 'utf-8' ) ;
472
+ }
473
+
474
+ const cachedContent = fileContentCache . get ( filePath ) ;
475
+
476
+ // Return cached content if it's still valid
477
+ if ( cachedContent && cachedContent . timestamp >= stats . mtime . getTime ( ) ) {
478
+ return cachedContent . content ;
479
+ }
480
+
481
+ // Read file content
482
+ const content = fs . readFileSync ( filePath , 'utf-8' ) ;
483
+
484
+ // Manage cache size - remove oldest entries if cache is full
485
+ if ( fileContentCache . size >= FILE_CACHE_MAX_SIZE ) {
486
+ const oldestKey = fileContentCache . keys ( ) . next ( ) . value ;
487
+ if ( oldestKey ) {
488
+ fileContentCache . delete ( oldestKey ) ;
489
+ }
490
+ }
491
+
492
+ // Cache the content
493
+ fileContentCache . set ( filePath , {
494
+ content,
495
+ timestamp : stats . mtime . getTime ( )
496
+ } ) ;
497
+
498
+ return content ;
499
+ } catch ( error ) {
500
+ console . error ( `Error reading file ${ filePath } :` , error ) ;
501
+ return null ;
502
+ }
503
+ }
504
+
505
+ // Function to clear file content cache (useful for testing or memory management)
506
+ export function clearFileContentCache ( ) : void {
507
+ fileContentCache . clear ( ) ;
508
+ }
509
+
510
+ // Function to invalidate cache for a specific file
511
+ export function invalidateFileCache ( filePath : string ) : void {
512
+ fileContentCache . delete ( filePath ) ;
513
+ reportCache . delete ( filePath ) ;
514
+ lineCountCache . delete ( filePath ) ;
515
+ }
516
+
457
517
export function parseReportTitle ( filePath : string ) : string {
458
518
try {
459
519
const report = getReportContent ( filePath ) ;
0 commit comments