Skip to content

Commit 8ea85aa

Browse files
author
Michael Johnston
committed
Merge pull request Flipboard#32 from darkyen/patch-1
LRU for image-cache
2 parents d8c58d7 + 2ae5d4e commit 8ea85aa

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

lib/ImageCache.js

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,65 @@ assign(Img.prototype, EventEmitter.prototype, {
7777
});
7878

7979
var kInstancePoolLength = 300;
80-
var _instancePool = [];
8180

82-
function getPooledImage (src) {
83-
for (var i=0, len=_instancePool.length; i < len; i++) {
84-
if (_instancePool[i].getOriginalSrc() === src) {
85-
return _instancePool[i];
81+
var _instancePool = {
82+
length: 0,
83+
// Keep all the nodes in memory.
84+
elements: {
85+
86+
},
87+
88+
// Push with 0 frequency
89+
push: function (hash, data) {
90+
this.length++;
91+
this.elements[hash] = {
92+
hash: hash, // Helps identifying
93+
freq: 0,
94+
data: data
95+
};
96+
},
97+
98+
get: function (path) {
99+
var element = this.elements[path];
100+
101+
if( element ){
102+
element.freq++;
103+
return element.data;
104+
}
105+
106+
return null;
107+
},
108+
109+
// used to explicitely remove the path
110+
removeElement: function (path) {
111+
// Now almighty GC can claim this soul
112+
var element = this.elements[path];
113+
delete this.elements[path];
114+
this.length--;
115+
return element;
116+
},
117+
118+
_reduceLeastUsed: function (least, currentHash) {
119+
var current = _instancePool.elements[currentHash];
120+
121+
if( least.freq > current.freq ){
122+
return current;
86123
}
124+
125+
return least;
126+
},
127+
128+
popLeastUsed: function () {
129+
var reducer = _instancePool._reduceLeastUsed;
130+
var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });
131+
132+
if( minUsed.hash ){
133+
return this.removeElement(minUsed.hash);
134+
}
135+
136+
return null;
87137
}
88-
return null;
89-
}
138+
};
90139

91140
var ImageCache = {
92141

@@ -96,14 +145,14 @@ var ImageCache = {
96145
* @return {Img}
97146
*/
98147
get: function (src) {
99-
var image = getPooledImage(src);
148+
var image = _instancePool.get(src);
100149
if (!image) {
101-
// Simple FIFO queue
150+
// Awesome LRU
102151
image = new Img(src);
103152
if (_instancePool.length >= kInstancePoolLength) {
104-
_instancePool.shift().destructor();
153+
_instancePool.popLeastUsed().destructor();
105154
}
106-
_instancePool.push(image);
155+
_instancePool.push(image.getOriginalSrc(), image);
107156
}
108157
return image;
109158
}

0 commit comments

Comments
 (0)