@@ -29,17 +29,6 @@ function MODEL_ID(resource: URI): string {
29
29
return resource . toString ( ) ;
30
30
}
31
31
32
- function computeModelSha1 ( model : ITextModel ) : string {
33
- // compute the sha1
34
- const shaComputer = new StringSHA1 ( ) ;
35
- const snapshot = model . createSnapshot ( ) ;
36
- let text : string | null ;
37
- while ( ( text = snapshot . read ( ) ) ) {
38
- shaComputer . update ( text ) ;
39
- }
40
- return shaComputer . digest ( ) ;
41
- }
42
-
43
32
class ModelData implements IDisposable {
44
33
45
34
private readonly _modelEventListeners = new DisposableStore ( ) ;
@@ -337,7 +326,12 @@ export class ModelService extends Disposable implements IModelService {
337
326
if ( resource && this . _disposedModels . has ( MODEL_ID ( resource ) ) ) {
338
327
const disposedModelData = this . _removeDisposedModel ( resource ) ! ;
339
328
const elements = this . _undoRedoService . getElements ( resource ) ;
340
- const sha1IsEqual = ( computeModelSha1 ( model ) === disposedModelData . sha1 ) ;
329
+ const sha1Computer = this . _getSHA1Computer ( ) ;
330
+ const sha1IsEqual = (
331
+ sha1Computer . canComputeSHA1 ( model )
332
+ ? sha1Computer . computeSHA1 ( model ) === disposedModelData . sha1
333
+ : false
334
+ ) ;
341
335
if ( sha1IsEqual || disposedModelData . sharesUndoRedoStack ) {
342
336
for ( const element of elements . past ) {
343
337
if ( isEditStackElement ( element ) && element . matchesResource ( resource ) ) {
@@ -535,15 +529,16 @@ export class ModelService extends Disposable implements IModelService {
535
529
}
536
530
537
531
const maxMemory = ModelService . MAX_MEMORY_FOR_CLOSED_FILES_UNDO_STACK ;
532
+ const sha1Computer = this . _getSHA1Computer ( ) ;
538
533
if ( ! maintainUndoRedoStack ) {
539
534
if ( ! sharesUndoRedoStack ) {
540
535
const initialUndoRedoSnapshot = modelData . model . getInitialUndoRedoSnapshot ( ) ;
541
536
if ( initialUndoRedoSnapshot !== null ) {
542
537
this . _undoRedoService . restoreSnapshot ( initialUndoRedoSnapshot ) ;
543
538
}
544
539
}
545
- } else if ( ! sharesUndoRedoStack && heapSize > maxMemory ) {
546
- // the undo stack for this file would never fit in the configured memory, so don't bother with it.
540
+ } else if ( ! sharesUndoRedoStack && ( heapSize > maxMemory || ! sha1Computer . canComputeSHA1 ( model ) ) ) {
541
+ // the undo stack for this file would never fit in the configured memory or the file is very large , so don't bother with it.
547
542
const initialUndoRedoSnapshot = modelData . model . getInitialUndoRedoSnapshot ( ) ;
548
543
if ( initialUndoRedoSnapshot !== null ) {
549
544
this . _undoRedoService . restoreSnapshot ( initialUndoRedoSnapshot ) ;
@@ -552,7 +547,7 @@ export class ModelService extends Disposable implements IModelService {
552
547
this . _ensureDisposedModelsHeapSize ( maxMemory - heapSize ) ;
553
548
// We only invalidate the elements, but they remain in the undo-redo service.
554
549
this . _undoRedoService . setElementsValidFlag ( model . uri , false , ( element ) => ( isEditStackElement ( element ) && element . matchesResource ( model . uri ) ) ) ;
555
- this . _insertDisposedModel ( new DisposedModelInfo ( model . uri , modelData . model . getInitialUndoRedoSnapshot ( ) , Date . now ( ) , sharesUndoRedoStack , heapSize , computeModelSha1 ( model ) , model . getVersionId ( ) , model . getAlternativeVersionId ( ) ) ) ;
550
+ this . _insertDisposedModel ( new DisposedModelInfo ( model . uri , modelData . model . getInitialUndoRedoSnapshot ( ) , Date . now ( ) , sharesUndoRedoStack , heapSize , sha1Computer . computeSHA1 ( model ) , model . getVersionId ( ) , model . getAlternativeVersionId ( ) ) ) ;
556
551
}
557
552
558
553
delete this . _models [ modelId ] ;
@@ -572,4 +567,33 @@ export class ModelService extends Disposable implements IModelService {
572
567
ModelService . _setModelOptionsForModel ( model , newOptions , oldOptions ) ;
573
568
this . _onModelModeChanged . fire ( { model, oldLanguageId : oldLanguageId } ) ;
574
569
}
570
+
571
+ protected _getSHA1Computer ( ) : ITextModelSHA1Computer {
572
+ return new DefaultModelSHA1Computer ( ) ;
573
+ }
574
+ }
575
+
576
+ export interface ITextModelSHA1Computer {
577
+ canComputeSHA1 ( model : ITextModel ) : boolean ;
578
+ computeSHA1 ( model : ITextModel ) : string ;
579
+ }
580
+
581
+ export class DefaultModelSHA1Computer implements ITextModelSHA1Computer {
582
+
583
+ public static MAX_MODEL_SIZE = 10 * 1024 * 1024 ; // takes 200ms to compute a sha1 on a 10MB model on a new machine
584
+
585
+ canComputeSHA1 ( model : ITextModel ) : boolean {
586
+ return ( model . getValueLength ( ) <= DefaultModelSHA1Computer . MAX_MODEL_SIZE ) ;
587
+ }
588
+
589
+ computeSHA1 ( model : ITextModel ) : string {
590
+ // compute the sha1
591
+ const shaComputer = new StringSHA1 ( ) ;
592
+ const snapshot = model . createSnapshot ( ) ;
593
+ let text : string | null ;
594
+ while ( ( text = snapshot . read ( ) ) ) {
595
+ shaComputer . update ( text ) ;
596
+ }
597
+ return shaComputer . digest ( ) ;
598
+ }
575
599
}
0 commit comments