Skip to content

Commit 815b3a7

Browse files
committed
Using LRU Cache instead of the old backingStore
1 parent c4f985e commit 815b3a7

File tree

1 file changed

+99
-98
lines changed

1 file changed

+99
-98
lines changed

src/LRUCache.js

Lines changed: 99 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -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

146147
module.exports = LRUCacheByLinkList

0 commit comments

Comments
 (0)