@@ -587,18 +587,22 @@ export class LinkedMap<K, V> {
587587 private _tail : Item < K , V > | undefined ;
588588 private _size : number ;
589589
590+ private _state : number ;
591+
590592 constructor ( ) {
591593 this . _map = new Map < K , Item < K , V > > ( ) ;
592594 this . _head = undefined ;
593595 this . _tail = undefined ;
594596 this . _size = 0 ;
597+ this . _state = 0 ;
595598 }
596599
597600 clear ( ) : void {
598601 this . _map . clear ( ) ;
599602 this . _head = undefined ;
600603 this . _tail = undefined ;
601604 this . _size = 0 ;
605+ this . _state ++ ;
602606 }
603607
604608 isEmpty ( ) : boolean {
@@ -701,34 +705,18 @@ export class LinkedMap<K, V> {
701705 }
702706 }
703707
704- values ( ) : V [ ] {
705- const result : V [ ] = [ ] ;
706- let current = this . _head ;
707- while ( current ) {
708- result . push ( current . value ) ;
709- current = current . next ;
710- }
711- return result ;
712- }
713-
714- keys ( ) : K [ ] {
715- const result : K [ ] = [ ] ;
716- let current = this . _head ;
717- while ( current ) {
718- result . push ( current . key ) ;
719- current = current . next ;
720- }
721- return result ;
722- }
723-
724- /* VS Code / Monaco editor runs on es5 which has no Symbol.iterator
725708 keys ( ) : IterableIterator < K > {
726- const current = this._head;
709+ const map = this ;
710+ const state = this . _state ;
711+ let current = this . _head ;
727712 const iterator : IterableIterator < K > = {
728713 [ Symbol . iterator ] ( ) {
729714 return iterator ;
730715 } ,
731- next():IteratorResult<K> {
716+ next ( ) : IteratorResult < K > {
717+ if ( map . _state !== state ) {
718+ throw new Error ( `Map got modified during iteration.` ) ;
719+ }
732720 if ( current ) {
733721 const result = { value : current . key , done : false } ;
734722 current = current . next ;
@@ -742,12 +730,17 @@ export class LinkedMap<K, V> {
742730 }
743731
744732 values ( ) : IterableIterator < V > {
745- const current = this._head;
733+ const map = this ;
734+ const state = this . _state ;
735+ let current = this . _head ;
746736 const iterator : IterableIterator < V > = {
747737 [ Symbol . iterator ] ( ) {
748738 return iterator ;
749739 } ,
750- next():IteratorResult<V> {
740+ next ( ) : IteratorResult < V > {
741+ if ( map . _state !== state ) {
742+ throw new Error ( `Map got modified during iteration.` ) ;
743+ }
751744 if ( current ) {
752745 const result = { value : current . value , done : false } ;
753746 current = current . next ;
@@ -759,7 +752,34 @@ export class LinkedMap<K, V> {
759752 } ;
760753 return iterator ;
761754 }
762- */
755+
756+ entries ( ) : IterableIterator < [ K , V ] > {
757+ const map = this ;
758+ const state = this . _state ;
759+ let current = this . _head ;
760+ const iterator : IterableIterator < [ K , V ] > = {
761+ [ Symbol . iterator ] ( ) {
762+ return iterator ;
763+ } ,
764+ next ( ) : IteratorResult < [ K , V ] > {
765+ if ( map . _state !== state ) {
766+ throw new Error ( `Map got modified during iteration.` ) ;
767+ }
768+ if ( current ) {
769+ const result : IteratorResult < [ K , V ] > = { value : [ current . key , current . value ] , done : false } ;
770+ current = current . next ;
771+ return result ;
772+ } else {
773+ return { value : undefined , done : true } ;
774+ }
775+ }
776+ } ;
777+ return iterator ;
778+ }
779+
780+ [ Symbol . iterator ] ( ) : IterableIterator < [ K , V ] > {
781+ return this . entries ( ) ;
782+ }
763783
764784 protected trimOld ( newSize : number ) {
765785 if ( newSize >= this . size ) {
@@ -781,6 +801,7 @@ export class LinkedMap<K, V> {
781801 if ( current ) {
782802 current . previous = undefined ;
783803 }
804+ this . _state ++ ;
784805 }
785806
786807 private addItemFirst ( item : Item < K , V > ) : void {
@@ -794,6 +815,7 @@ export class LinkedMap<K, V> {
794815 this . _head . previous = item ;
795816 }
796817 this . _head = item ;
818+ this . _state ++ ;
797819 }
798820
799821 private addItemLast ( item : Item < K , V > ) : void {
@@ -807,6 +829,7 @@ export class LinkedMap<K, V> {
807829 this . _tail . next = item ;
808830 }
809831 this . _tail = item ;
832+ this . _state ++ ;
810833 }
811834
812835 private removeItem ( item : Item < K , V > ) : void {
@@ -843,6 +866,7 @@ export class LinkedMap<K, V> {
843866 }
844867 item . next = undefined ;
845868 item . previous = undefined ;
869+ this . _state ++ ;
846870 }
847871
848872 private touch ( item : Item < K , V > , touch : Touch ) : void {
@@ -879,6 +903,7 @@ export class LinkedMap<K, V> {
879903 item . next = this . _head ;
880904 this . _head . previous = item ;
881905 this . _head = item ;
906+ this . _state ++ ;
882907 } else if ( touch === Touch . AsNew ) {
883908 if ( item === this . _tail ) {
884909 return ;
@@ -902,6 +927,7 @@ export class LinkedMap<K, V> {
902927 item . previous = this . _tail ;
903928 this . _tail . next = item ;
904929 this . _tail = item ;
930+ this . _state ++ ;
905931 }
906932 }
907933
@@ -953,8 +979,8 @@ export class LRUCache<K, V> extends LinkedMap<K, V> {
953979 this . checkTrim ( ) ;
954980 }
955981
956- get ( key : K ) : V | undefined {
957- return super . get ( key , Touch . AsNew ) ;
982+ get ( key : K , touch : Touch = Touch . AsNew ) : V | undefined {
983+ return super . get ( key , touch ) ;
958984 }
959985
960986 peek ( key : K ) : V | undefined {
0 commit comments