@@ -14,8 +14,8 @@ import { predictionTrackerDefaultConfig } from '../models/constants'
1414export interface FileTrackerConfig {
1515 /** Maximum number of files to track (default: 15) */
1616 maxFiles : number
17- /** Maximum total size in kilobytes (default: 200) */
18- maxTotalSizeKb : number
17+ /** Maximum total size of all snapshots in kilobytes (default: 200) */
18+ maxStorageSizeKb : number
1919 /** Debounce interval in milliseconds (default: 2000) */
2020 debounceIntervalMs : number
2121 /** Maximum age of snapshots in milliseconds (default: 30000) */
@@ -37,13 +37,11 @@ export interface FileSnapshot {
3737export class PredictionTracker {
3838 private snapshots : Map < string , FileSnapshot [ ] > = new Map ( )
3939 readonly config : FileTrackerConfig
40- private totalSize : number = 0
40+ private storageSize : number = 0
4141 private storagePath ?: string
4242 private debounceTracker : Set < string > = new Set ( )
4343
4444 constructor ( extensionContext : vscode . ExtensionContext , config ?: Partial < FileTrackerConfig > ) {
45- getLogger ( ) . debug ( 'Initializing PredictionTracker' )
46-
4745 this . config = {
4846 ...predictionTrackerDefaultConfig ,
4947 ...config ,
@@ -60,7 +58,7 @@ export class PredictionTracker {
6058 const filePath = document . uri . fsPath
6159 getLogger ( ) . debug ( `Processing edit for file: ${ filePath } ` )
6260
63- if ( ! this . storagePath || filePath . startsWith ( 'untitled:' ) || ! document . uri . scheme . startsWith ( 'file' ) ) {
61+ if ( ! this . storagePath || ! document . uri . scheme . startsWith ( 'file' ) ) {
6462 return
6563 }
6664
@@ -77,7 +75,7 @@ export class PredictionTracker {
7775 const size = Buffer . byteLength ( content , 'utf8' )
7876
7977 const timestamp = Date . now ( )
80- const storageKey = this . generateStorageKey ( filePath , timestamp )
78+ const storageKey = ` ${ filePath } - ${ timestamp } `
8179
8280 const snapshot : FileSnapshot = {
8381 filePath,
@@ -101,7 +99,7 @@ export class PredictionTracker {
10199
102100 fileSnapshots . push ( snapshot )
103101 this . snapshots . set ( filePath , fileSnapshots )
104- this . totalSize += size
102+ this . storageSize += size
105103
106104 await this . enforceMemoryLimits ( )
107105
@@ -110,8 +108,7 @@ export class PredictionTracker {
110108 const index = fileSnapshots . indexOf ( snapshot )
111109 if ( index !== - 1 ) {
112110 fileSnapshots . splice ( index , 1 )
113- this . totalSize -= size
114- await this . deleteSnapshotFromStorage ( snapshot )
111+ await this . deleteSnapshot ( snapshot )
115112 if ( fileSnapshots . length === 0 ) {
116113 this . snapshots . delete ( filePath )
117114 }
@@ -123,20 +120,12 @@ export class PredictionTracker {
123120 }
124121 }
125122
126- /**
127- * Generates a unique storage key for a snapshot
128- */
129- private generateStorageKey ( filePath : string , timestamp : number ) : string {
130- const fileName = path . basename ( filePath )
131- return `${ fileName } -${ timestamp } `
132- }
133-
134123 /**
135124 * Enforces memory limits by removing old snapshots if necessary
136125 */
137126 private async enforceMemoryLimits ( ) : Promise < void > {
138127 // Enforce total size limit
139- while ( this . totalSize > this . config . maxTotalSizeKb * 1024 ) {
128+ while ( this . storageSize > this . config . maxStorageSizeKb * 1024 ) {
140129 const oldestFile = this . findOldestFile ( )
141130 if ( ! oldestFile ) {
142131 break
@@ -150,33 +139,13 @@ export class PredictionTracker {
150139
151140 const removedSnapshot = fileSnapshots . shift ( )
152141 if ( removedSnapshot ) {
153- this . totalSize -= removedSnapshot . size
154- await this . deleteSnapshotFromStorage ( removedSnapshot )
142+ await this . deleteSnapshot ( removedSnapshot )
155143 }
156144
157145 if ( fileSnapshots . length === 0 ) {
158146 this . snapshots . delete ( oldestFile )
159147 }
160148 }
161-
162- // Enforce max files limit
163- while ( this . snapshots . size > this . config . maxFiles ) {
164- const oldestFile = this . findOldestFile ( )
165- if ( ! oldestFile ) {
166- break
167- }
168-
169- const fileSnapshots = this . snapshots . get ( oldestFile )
170- if ( fileSnapshots ) {
171- // Subtract all snapshot sizes from the total
172- for ( const snapshot of fileSnapshots ) {
173- this . totalSize -= snapshot . size
174- await this . deleteSnapshotFromStorage ( snapshot )
175- }
176- }
177-
178- this . snapshots . delete ( oldestFile )
179- }
180149 }
181150
182151 /**
@@ -213,8 +182,7 @@ export class PredictionTracker {
213182 const validSnapshots = snapshots . filter ( ( snapshot ) => {
214183 const isValid = now - snapshot . timestamp <= maxAge
215184 if ( ! isValid ) {
216- this . totalSize -= snapshot . size
217- void this . deleteSnapshotFromStorage ( snapshot )
185+ void this . deleteSnapshot ( snapshot )
218186 }
219187 return isValid
220188 } )
@@ -271,21 +239,20 @@ export class PredictionTracker {
271239 await fs . mkdir ( snapshotsDir )
272240 }
273241
274- const filePath = path . join ( snapshotsDir , `${ storageKey } .content ` )
242+ const filePath = path . join ( snapshotsDir , `${ storageKey } .nep-snapshot ` )
275243 await fs . writeFile ( filePath , content )
276244 }
277245
278- /**
279- * Deletes a snapshot content from Storage
280- * @param snapshot The snapshot to delete
281- */
282- private async deleteSnapshotFromStorage ( snapshot : FileSnapshot ) : Promise < void > {
246+ private async deleteSnapshot ( snapshot : FileSnapshot ) : Promise < void > {
283247 if ( ! this . storagePath ) {
284248 return
285249 }
286250
251+ // Update the storage size
252+ this . storageSize -= snapshot . size
253+
287254 const snapshotsDir = path . join ( this . storagePath , 'AmazonQ-file-snapshots' )
288- const filePath = path . join ( snapshotsDir , `${ snapshot . storageKey } .content ` )
255+ const filePath = path . join ( snapshotsDir , `${ snapshot . storageKey } .nep-snapshot ` )
289256
290257 if ( await fs . exists ( filePath ) ) {
291258 try {
@@ -307,7 +274,7 @@ export class PredictionTracker {
307274 }
308275
309276 const snapshotsDir = path . join ( this . storagePath , 'AmazonQ-file-snapshots' )
310- const filePath = path . join ( snapshotsDir , `${ snapshot . storageKey } .content ` )
277+ const filePath = path . join ( snapshotsDir , `${ snapshot . storageKey } .nep-snapshot ` )
311278
312279 try {
313280 return await fs . readFileText ( filePath )
@@ -389,11 +356,11 @@ export class PredictionTracker {
389356
390357 // First, collect all the metadata files
391358 for ( const [ filename , fileType ] of files ) {
392- if ( ! filename . endsWith ( '.content ' ) || fileType !== vscode . FileType . File ) {
359+ if ( ! filename . endsWith ( '.nep-snapshot ' ) || fileType !== vscode . FileType . File ) {
393360 continue
394361 }
395362
396- const storageKey = filename . substring ( 0 , filename . length - '.content ' . length )
363+ const storageKey = filename . substring ( 0 , filename . length - '.nep-snapshot ' . length )
397364 const parts = storageKey . split ( '-' )
398365 const timestamp = parseInt ( parts [ parts . length - 1 ] , 10 )
399366 const originalFilename = parts . slice ( 0 , parts . length - 1 ) . join ( '-' )
@@ -407,9 +374,10 @@ export class PredictionTracker {
407374
408375 // Now process each file that we found
409376 for ( const [ storageKey , metadata ] of metadataFiles . entries ( ) ) {
410- const contentPath = path . join ( snapshotsDir , `${ storageKey } .content ` )
377+ const contentPath = path . join ( snapshotsDir , `${ storageKey } .nep-snapshot ` )
411378
412379 try {
380+ // if original file no longer exists, delete the snapshot
413381 if ( ! ( await fs . exists ( metadata . filePath ) ) ) {
414382 await fs . delete ( contentPath )
415383 continue
@@ -431,7 +399,7 @@ export class PredictionTracker {
431399 const fileSnapshots = this . snapshots . get ( metadata . filePath ) || [ ]
432400 fileSnapshots . push ( snapshot )
433401 this . snapshots . set ( metadata . filePath , fileSnapshots )
434- this . totalSize += size
402+ this . storageSize += size
435403 } catch ( err ) {
436404 // Remove invalid files
437405 getLogger ( ) . error ( `Error processing snapshot file ${ storageKey } : ${ err } ` )
@@ -457,6 +425,10 @@ export class PredictionTracker {
457425 }
458426 }
459427
428+ public getTotalSize ( ) {
429+ return this . storageSize
430+ }
431+
460432 /**
461433 * Disposes of resources used by the tracker
462434 */
0 commit comments