@@ -45,210 +45,210 @@ class FrequencyMap extends Map {
45
45
}
46
46
47
47
class LFUCache {
48
- #capacity
49
- #frequencyMap
48
+ #capacity
49
+ #frequencyMap
50
50
51
- /**
51
+ /**
52
52
* @param {number } capacity - The range of LFUCache
53
53
* @returns {LFUCache } - sealed
54
54
*/
55
- constructor ( capacity ) {
56
- this . #capacity = capacity
57
- this . #frequencyMap = new FrequencyMap ( )
58
- this . misses = 0
59
- this . hits = 0
60
- this . cache = new Map ( )
61
-
62
- return Object . seal ( this )
63
- }
55
+ constructor ( capacity ) {
56
+ this . #capacity = capacity
57
+ this . #frequencyMap = new FrequencyMap ( )
58
+ this . misses = 0
59
+ this . hits = 0
60
+ this . cache = new Map ( )
61
+
62
+ return Object . seal ( this )
63
+ }
64
64
65
- /**
65
+ /**
66
66
* Get the capacity of the LFUCache
67
67
* @returns {number }
68
68
*/
69
- get capacity ( ) {
70
- return this . #capacity
71
- }
69
+ get capacity ( ) {
70
+ return this . #capacity
71
+ }
72
72
73
- /**
73
+ /**
74
74
* Get the current size of LFUCache
75
75
* @returns {number }
76
76
*/
77
- get size ( ) {
78
- return this . cache . size
79
- }
77
+ get size ( ) {
78
+ return this . cache . size
79
+ }
80
80
81
- /**
81
+ /**
82
82
* Set the capacity of the LFUCache if you decrease the capacity its removed CacheNodes following the LFU - least frequency used
83
83
*/
84
- set capacity ( newCapacity ) {
85
- if ( this . #capacity > newCapacity ) {
86
- let diff = this . #capacity - newCapacity // get the decrement number of capacity
84
+ set capacity ( newCapacity ) {
85
+ if ( this . #capacity > newCapacity ) {
86
+ let diff = this . #capacity - newCapacity // get the decrement number of capacity
87
87
88
- while ( diff -- ) {
89
- this . #removeCacheNode( )
90
- }
91
-
92
- this . cache . size === 0 && this . #frequencyMap. clear ( )
88
+ while ( diff -- ) {
89
+ this . #removeCacheNode( )
93
90
}
94
91
95
- this . #capacity = newCapacity
92
+ this . cache . size === 0 && this . #frequencyMap . clear ( )
96
93
}
97
94
98
- get info ( ) {
99
- return Object . freeze ( {
100
- misses : this . misses ,
101
- hits : this . hits ,
102
- capacity : this . capacity ,
103
- currentSize : this . size ,
104
- leastFrequency : this . leastFrequency
105
- } )
106
- }
95
+ this . #capacity = newCapacity
96
+ }
107
97
108
- get leastFrequency ( ) {
109
- const freqCacheIterator = this . #frequencyMap. keys ( )
110
- let leastFrequency = freqCacheIterator . next ( ) . value || null
98
+ get info ( ) {
99
+ return Object . freeze ( {
100
+ misses : this . misses ,
101
+ hits : this . hits ,
102
+ capacity : this . capacity ,
103
+ currentSize : this . size ,
104
+ leastFrequency : this . leastFrequency
105
+ } )
106
+ }
111
107
112
- // select the non-empty frequency Set
113
- while ( this . #frequencyMap. get ( leastFrequency ) ?. size === 0 ) {
114
- leastFrequency = freqCacheIterator . next ( ) . value
115
- }
108
+ get leastFrequency ( ) {
109
+ const freqCacheIterator = this . #frequencyMap. keys ( )
110
+ let leastFrequency = freqCacheIterator . next ( ) . value || null
116
111
117
- return leastFrequency
112
+ // select the non-empty frequency Set
113
+ while ( this . #frequencyMap. get ( leastFrequency ) ?. size === 0 ) {
114
+ leastFrequency = freqCacheIterator . next ( ) . value
118
115
}
119
116
120
- #removeCacheNode ( ) {
121
- const leastFreqSet = this . #frequencyMap. get ( this . leastFrequency )
122
- // Select the least recently used node from the least Frequency set
123
- const LFUNode = leastFreqSet . values ( ) . next ( ) . value
117
+ return leastFrequency
118
+ }
124
119
125
- leastFreqSet . delete ( LFUNode )
126
- this . cache . delete ( LFUNode . key )
127
- }
120
+ #removeCacheNode ( ) {
121
+ const leastFreqSet = this . #frequencyMap. get ( this . leastFrequency )
122
+ // Select the least recently used node from the least Frequency set
123
+ const LFUNode = leastFreqSet . values ( ) . next ( ) . value
124
+
125
+ leastFreqSet . delete ( LFUNode )
126
+ this . cache . delete ( LFUNode . key )
127
+ }
128
128
129
- /**
129
+ /**
130
130
* if key exist then return true otherwise false
131
131
* @param {any } key
132
132
* @returns {boolean }
133
133
*/
134
- has ( key ) {
135
- key = String ( key ) // converted to string
134
+ has ( key ) {
135
+ key = String ( key ) // converted to string
136
136
137
- return this . cache . has ( key )
138
- }
137
+ return this . cache . has ( key )
138
+ }
139
139
140
- /**
140
+ /**
141
141
* @method get
142
142
* @description - This method return the value of key & refresh the frequencyMap by the oldNode
143
143
* @param {string } key
144
144
* @returns {any }
145
145
*/
146
- get ( key ) {
147
- key = String ( key ) // converted to string
146
+ get ( key ) {
147
+ key = String ( key ) // converted to string
148
148
149
- if ( this . cache . has ( key ) ) {
150
- const oldNode = this . cache . get ( key )
151
- this . #frequencyMap. refresh ( oldNode )
149
+ if ( this . cache . has ( key ) ) {
150
+ const oldNode = this . cache . get ( key )
151
+ this . #frequencyMap. refresh ( oldNode )
152
152
153
- this . hits ++
153
+ this . hits ++
154
154
155
- return oldNode . value
156
- }
157
-
158
- this . misses ++
159
- return null
155
+ return oldNode . value
160
156
}
161
157
162
- /**
158
+ this . misses ++
159
+ return null
160
+ }
161
+
162
+ /**
163
163
* @method set
164
164
* @description - This method stored the value by key & add frequency if it doesn't exist
165
165
* @param {string } key
166
166
* @param {any } value
167
167
* @param {number } frequency
168
168
* @returns {LFUCache }
169
169
*/
170
- set ( key , value , frequency = 1 ) {
171
- key = String ( key ) // converted to string
170
+ set ( key , value , frequency = 1 ) {
171
+ key = String ( key ) // converted to string
172
172
173
- if ( this . #capacity === 0 ) {
174
- throw new RangeError ( 'LFUCache ERROR: The Capacity is 0' )
175
- }
173
+ if ( this . #capacity === 0 ) {
174
+ throw new RangeError ( 'LFUCache ERROR: The Capacity is 0' )
175
+ }
176
176
177
- if ( this . cache . has ( key ) ) {
178
- const node = this . cache . get ( key )
179
- node . value = value
177
+ if ( this . cache . has ( key ) ) {
178
+ const node = this . cache . get ( key )
179
+ node . value = value
180
180
181
- this . #frequencyMap. refresh ( node )
181
+ this . #frequencyMap. refresh ( node )
182
182
183
- return this
184
- }
183
+ return this
184
+ }
185
185
186
- // if the cache size is full, then it's delete the Least Frequency Used node
187
- if ( this . #capacity === this . cache . size ) {
188
- this . #removeCacheNode( )
189
- }
186
+ // if the cache size is full, then it's delete the Least Frequency Used node
187
+ if ( this . #capacity === this . cache . size ) {
188
+ this . #removeCacheNode( )
189
+ }
190
190
191
- const newNode = new CacheNode ( key , value , frequency )
191
+ const newNode = new CacheNode ( key , value , frequency )
192
192
193
- this . cache . set ( key , newNode )
194
- this . #frequencyMap. insert ( newNode )
193
+ this . cache . set ( key , newNode )
194
+ this . #frequencyMap. insert ( newNode )
195
195
196
- return this
197
- }
196
+ return this
197
+ }
198
198
199
- /**
199
+ /**
200
200
* @method parse
201
201
* @description - This method receive a valid LFUCache JSON & run JSON.prase() method and merge with existing LFUCache
202
202
* @param {JSON } json
203
203
* @returns {LFUCache } - merged
204
204
*/
205
- parse ( json ) {
206
- const { misses, hits, cache } = JSON . parse ( json )
205
+ parse ( json ) {
206
+ const { misses, hits, cache } = JSON . parse ( json )
207
207
208
- this . misses += misses ?? 0
209
- this . hits += hits ?? 0
208
+ this . misses += misses ?? 0
209
+ this . hits += hits ?? 0
210
210
211
- for ( const key in cache ) {
212
- const { value, frequency } = cache [ key ]
213
- this . set ( key , value , frequency )
214
- }
215
-
216
- return this
211
+ for ( const key in cache ) {
212
+ const { value, frequency } = cache [ key ]
213
+ this . set ( key , value , frequency )
217
214
}
218
215
219
- /**
216
+ return this
217
+ }
218
+
219
+ /**
220
220
* @method clear
221
221
* @description - This method cleared the whole LFUCache
222
222
* @returns {LFUCache }
223
223
*/
224
- clear ( ) {
225
- this . cache . clear ( )
226
- this . #frequencyMap. clear ( )
224
+ clear ( ) {
225
+ this . cache . clear ( )
226
+ this . #frequencyMap. clear ( )
227
227
228
- return this
229
- }
228
+ return this
229
+ }
230
230
231
- /**
231
+ /**
232
232
* @method toString
233
233
* @description - This method generate a JSON format of LFUCache & return it.
234
234
* @param {number } indent
235
235
* @returns {string } - JSON
236
236
*/
237
- toString ( indent ) {
238
- const replacer = ( _ , value ) => {
239
- if ( value instanceof Set ) {
240
- return [ ...value ]
241
- }
242
-
243
- if ( value instanceof Map ) {
244
- return Object . fromEntries ( value )
245
- }
237
+ toString ( indent ) {
238
+ const replacer = ( _ , value ) => {
239
+ if ( value instanceof Set ) {
240
+ return [ ...value ]
241
+ }
246
242
247
- return value
243
+ if ( value instanceof Map ) {
244
+ return Object . fromEntries ( value )
248
245
}
249
246
250
- return JSON . stringify ( this , replacer , indent )
247
+ return value
251
248
}
249
+
250
+ return JSON . stringify ( this , replacer , indent )
251
+ }
252
252
}
253
253
254
254
export default LFUCache
0 commit comments