Separated the LRU cache implementation.

This commit is contained in:
Thaddee Tyl
2014-04-27 23:47:12 +00:00
parent 87b4702953
commit 3da09b93b7
2 changed files with 50 additions and 29 deletions

45
lru-cache.js Normal file
View File

@@ -0,0 +1,45 @@
// Cache any data with a timestamp,
// remove only the oldest data.
function Cache(size) {
if (!this instanceof Cache) { return new Cache(size); }
this.size = size;
this.cache = Object.create(null);
this.cacheTime = Object.create(null);
this.cacheSize = 0;
}
Cache.prototype.set =
function addToCache(cacheIndex, cached) {
this.cache[cacheIndex] = cached;
var mostAncient = +(new Date());
this.cacheTime[cacheIndex] = mostAncient;
if (this.cacheSize >= this.size) {
// Find the most ancient image.
var ancientCacheIndex = cacheIndex;
for (var currentCacheIndex in this.cacheTime) {
if (mostAncient > this.cacheTime[currentCacheIndex]) {
mostAncient = this.cacheTime[currentCacheIndex];
ancientCacheIndex = currentCacheIndex;
}
}
// Delete that image.
delete this.cache[ancientCacheIndex];
delete this.cacheTime[ancientCacheIndex];
} else {
this.cacheSize++;
}
}
Cache.prototype.get =
function getFromCache(cacheIndex) {
this.cacheTime[cacheIndex] = +(new Date());
return this.cache[cacheIndex];
}
Cache.prototype.has =
function hasInCache(cacheIndex) {
return this.cache[cacheIndex] !== undefined;
}
module.exports = Cache;

View File

@@ -2,21 +2,18 @@ var fs = require('fs');
var os = require('os');
var path = require('path');
var phantom = require('phantomjs');
var LruCache = require('./lru-cache.js');
var childProcess = require('child_process');
var phantomScript = path.join(__dirname, 'phantomjs-svg2png.js');
var imgCache = Object.create(null);
var imgCacheTime = Object.create(null);
var imgCacheSize = 0;
// The following is an arbitrary limit (~1.5MB, 1.5kB/image).
var imgCacheMaxSize = 1000;
var imgCache = new LruCache(1000);
module.exports = function (svg, format, out, cb) {
var cacheIndex = format + svg;
if (imgCache[cacheIndex] !== undefined) {
if (imgCache.has(cacheIndex)) {
// We own a cache for this svg conversion.
(new DataStream(imgCache[cacheIndex])).pipe(out);
imgCacheTime[cacheIndex] = +(new Date());
(new DataStream(imgCache.get(cacheIndex))).pipe(out);
return;
}
var tmpFile = path.join(os.tmpdir(),
@@ -36,33 +33,12 @@ module.exports = function (svg, format, out, cb) {
// Remove the temporary file after use.
inStream.on('end', function() {
try { out.end(); } catch(e) {}
addToCache(cacheIndex, cached);
imgCache.set(cacheIndex, cached);
fs.unlink(tmpFile, cb);
});
});
};
function addToCache(cacheIndex, cached) {
imgCache[cacheIndex] = cached;
var mostAncient = +(new Date());
imgCacheTime[cacheIndex] = mostAncient;
if (imgCacheSize >= imgCacheMaxSize) {
// Find the most ancient image.
var ancientCacheIndex = cacheIndex;
for (var currentCacheIndex in imgCacheTime) {
if (mostAncient > imgCacheTime[currentCacheIndex]) {
mostAncient = imgCacheTime[currentCacheIndex];
ancientCacheIndex = currentCacheIndex;
}
}
// Delete that image.
delete imgCache[ancientCacheIndex];
delete imgCacheTime[ancientCacheIndex];
} else {
imgCacheSize++;
}
}
// Fake stream from the cache.
var Readable = require('stream').Readable;
var util = require('util');