Skip to content
This repository has been archived by the owner on Nov 14, 2018. It is now read-only.

Commit

Permalink
Fixed-size cache store for bitmap images.
Browse files Browse the repository at this point in the history
Part of issue #23.
  • Loading branch information
espadrine committed Jan 10, 2014
1 parent 2877a78 commit 4e458a1
Showing 1 changed file with 44 additions and 19 deletions.
63 changes: 44 additions & 19 deletions svg-to-img.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@ var childProcess = require('child_process');
var phantomScript = path.join(__dirname, 'phantomjs-svg2png.js');

var imgCache = Object.create(null);

// If available, use the font here.
var fontPath = './Verbana.ttf';
try {
// This happens at startup. Needn't be async.
var fontBase64 = fs.readFileSync(fontPath, 'base64');
} catch(e) {}
var imgCacheTime = Object.create(null);
var imgCacheSize = 0;
// The following is an arbitrary limit (~1.5MB, 1.5kB/image).
var imgCacheMaxSize = 1000;

module.exports = function (svg, format, out, cb) {
var cacheIndex = format + svg;
if (imgCache[cacheIndex] !== undefined) {
// We own a cache for this svg conversion.
imgCache[cacheIndex].pipe(out);
(new DataStream(imgCache[cacheIndex])).pipe(out);
imgCacheTime[cacheIndex] = +(new Date());
return;
}
var tmpFile = path.join(os.tmpdir(),
"svg2img-" + (Math.random()*2147483648|0) + "." + format);
Expand All @@ -37,21 +36,47 @@ module.exports = function (svg, format, out, cb) {
// Remove the temporary file after use.
inStream.on('end', function() {
out.end();
imgCache[cacheIndex] = streamFromData(cached);
addToCache(cacheIndex, cached);
fs.unlink(tmpFile, cb);
});
});
};

// Fake stream from the cache.
var stream = require('stream');
function streamFromData(data) {
var newStream = new stream.Readable();
newStream._read = function() {
for (var i = 0; i < data.length; i++) {
newStream.push(data[i]);
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;
}
}
newStream.push(null)
};
return newStream;
// 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');
function DataStream(data) {
Readable.call(this);
this.data = data;
this.i = 0;
}
util.inherits(DataStream, Readable);
DataStream.prototype._read = function() {
while (this.i < this.data.length) {
var stop = this.push(this.data[this.i]);
this.i++;
if (stop) { return; }
}
this.push(null);
};

0 comments on commit 4e458a1

Please sign in to comment.