@@ -9,138 +9,139 @@ function LRULinkListEntry(hash, obj) {
99 this . _next = null
1010}
1111
12- // My favorite so far.
13- function LRUCacheByLinkList ( length ) {
14- this . maxLength = length
15- this . reset ( )
16- }
17-
18- LRUCacheByLinkList . prototype . reset = ( ) => {
19- this . length = 0
20- this . _top = null
21- this . _bottom = null
22- this . _keyVals = { }
23- }
24-
25- LRUCacheByLinkList . prototype . detachElement = entry => {
26- const prev = entry . _prev
27- const next = entry . _next
28-
29- if ( prev !== null ) {
30- prev . _next = next
12+ class LRUCacheByLinkList {
13+ constructor ( length ) {
14+ this . maxLength = length
15+ this . reset ( )
3116 }
3217
33- if ( next !== null ) {
34- next . _prev = prev
18+ reset = ( ) => {
19+ this . length = 0
20+ this . _top = null
21+ this . _bottom = null
22+ this . _keyVals = { }
3523 }
3624
37- if ( entry === this . _top ) {
38- this . _top = next
39- }
25+ detachElement = entry => {
26+ const prev = entry . _prev
27+ const next = entry . _next
4028
41- if ( entry === this . _bottom ) {
42- this . _bottom = prev
43- }
29+ if ( prev !== null ) {
30+ prev . _next = next
31+ }
4432
45- this . length --
46- return entry
47- }
33+ if ( next !== null ) {
34+ next . _prev = prev
35+ }
4836
49- LRUCacheByLinkList . prototype . removeElement = entry => {
50- this . detachElement ( entry )
51- delete this . _keyVals [ entry . _hash ]
52- return entry . _datum
53- }
37+ if ( entry === this . _top ) {
38+ this . _top = next
39+ }
40+
41+ if ( entry === this . _bottom ) {
42+ this . _bottom = prev
43+ }
5444
55- LRUCacheByLinkList . prototype . insertAtTop = entry => {
56- if ( this . _top !== null ) {
57- this . _top . _prev = entry
58- entry . _next = this . _top
45+ this . length --
46+ return entry
5947 }
6048
61- if ( this . _bottom === null ) {
62- this . _bottom = entry
49+ removeElement = entry => {
50+ this . detachElement ( entry )
51+ delete this . _keyVals [ entry . _hash ]
52+ return entry . _datum
6353 }
6454
65- this . _top = entry
66- this . length ++
67- }
55+ insertAtTop = entry => {
56+ if ( this . _top !== null ) {
57+ this . _top . _prev = entry
58+ entry . _next = this . _top
59+ }
60+
61+ if ( this . _bottom === null ) {
62+ this . _bottom = entry
63+ }
6864
69- LRUCacheByLinkList . prototype . insertAtBottom = value => {
70- if ( this . _bottom !== null ) {
71- this . _bottom . _next = value
72- value . _prev = this . _bottom
65+ this . _top = entry
66+ this . length ++
7367 }
7468
75- if ( this . _top === null ) {
76- this . _top = value
69+ insertAtBottom = value => {
70+ if ( this . _bottom !== null ) {
71+ this . _bottom . _next = value
72+ value . _prev = this . _bottom
73+ }
74+
75+ if ( this . _top === null ) {
76+ this . _top = value
77+ }
78+
79+ this . _bottom = value
80+ this . length ++
7781 }
7882
79- this . _bottom = value
80- this . length ++
81- }
83+ set = ( key , value ) => {
84+ const existinEl = this . _keyVals [ key ]
8285
83- LRUCacheByLinkList . prototype . set = ( key , value ) => {
84- const existinEl = this . _keyVals [ key ]
86+ // Handling for dups
87+ if ( existinEl ) {
88+ if ( existinEl . _datum === value ) {
89+ // Don't change anything
90+ return
91+ }
8592
86- // Handling for dups
87- if ( existinEl ) {
88- if ( existinEl . _datum === value ) {
89- // Don't change anything
90- return
93+ // hardest part of code.
94+ this . removeElement ( existinEl )
9195 }
9296
93- // hardest part of code.
94- this . removeElement ( existinEl )
95- }
97+ value = new LRULinkListEntry ( key , value )
98+ this . _keyVals [ key ] = value
9699
97- value = new LRULinkListEntry ( key , value )
98- this . _keyVals [ key ] = value
100+ // Most likely it will only be equal
101+ // to purge the least used
99102
100- // Most likely it will only be equal
101- // to purge the least used
103+ if ( this . length === this . maxLength ) {
104+ this . removeLeastUsed ( )
105+ }
102106
103- if ( this . length === this . maxLength ) {
104- this . removeLeastUsed ( )
107+ this . insertAtTop ( value )
105108 }
106109
107- this . insertAtTop ( value )
108- }
110+ removeLeastUsed = ( ) => {
111+ // Buhahah this is easy.
112+ return this . removeElement ( this . _bottom )
113+ }
109114
110- LRUCacheByLinkList . prototype . removeLeastUsed = ( ) => {
111- // Buhahah this is easy.
112- return this . removeElement ( this . _bottom )
113- }
115+ get = key => {
116+ const value = this . _keyVals [ key ]
114117
115- LRUCacheByLinkList . prototype . get = key => {
116- const value = this . _keyVals [ key ]
118+ if ( value !== undefined ) {
119+ // Promote this as it got used
120+ this . promote ( value )
121+ return value . _datum
122+ }
117123
118- if ( value !== undefined ) {
119- // Promote this as it got used
120- this . promote ( value )
121- return value . _datum
124+ return null
122125 }
123126
124- return null
125- }
127+ // Remove the element
128+ // and push it from the front
129+ // so least recently used objects will end up at the end.
130+ promote = el => {
131+ // No need to promote
132+ if ( el === this . top ) {
133+ return
134+ }
126135
127- // Remove the element
128- // and push it from the front
129- // so least recently used objects will end up at the end.
130- LRUCacheByLinkList . prototype . promote = el => {
131- // No need to promote
132- if ( el === this . top ) {
133- return
136+ // seriously do we need to remove it ?
137+ this . detachElement ( el )
138+ this . insertAtTop ( el )
134139 }
135140
136- // seriously do we need to remove it ?
137- this . detachElement ( el )
138- this . insertAtTop ( el )
139- }
140-
141- // Call this method
142- LRUCacheByLinkList . prototype . forEach = cb => {
143- Object . keys ( this . _keyVals ) . forEach ( entry => cb ( entry . _datum ) )
141+ // Call this method
142+ forEach = cb => {
143+ Object . keys ( this . _keyVals ) . forEach ( entry => cb ( entry . _datum ) )
144+ }
144145}
145146
146147module . exports = LRUCacheByLinkList
0 commit comments