forked from mapbox/mapbox-studio-classic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcache.js
68 lines (63 loc) · 2.65 KB
/
cache.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
var util = require('util');
var path = require('path');
var crypto = require('crypto');
var MBTiles = require('mbtiles');
var cache = {};
function verbose(extra, err) {
err.message = extra + ': ' + err.message;
return err;
}
// Wrap the passed Source type to create a caching source.
module.exports = function(Source, cachedir) {
function CachingSource(uri, callback) {
return Source.call(this, uri, function(err, source) {
if (err) return callback(err);
if (!source._xml && !source.data) return callback(new Error('No hash data for caching source'));
var hash = crypto.createHash('md5')
.update(source._xml || source.data.id)
.digest('hex')
.substr(0,16);
var cachepath = path.join(cachedir, hash + '.mbtiles');
if (cache[cachepath]) {
source._mbtiles = cache[cachepath];
cache[cachepath]._cacheStats.hit++;
return callback(null, source);
}
// Pass filepath to node-mbtiles in uri object to avoid
// url.parse() upstream mishandling windows paths.
new MBTiles({
pathname: cachepath,
query: { batch: 1 }
}, function(err, mbtiles) {
if (err) return callback(verbose('MBTiles ' + cachepath, err));
source._mbtiles = mbtiles;
source._mbtiles.startWriting(function(err) {
if (err) return callback(verbose('startWriting ' + cachepath, err));
mbtiles._cacheStats = { hit:0, miss:1 };
cache[cachepath] = mbtiles;
return callback(null, source);
});
});
});
};
util.inherits(CachingSource, Source);
CachingSource.prototype.getTile = function(z,x,y,callback) {
if (!this._mbtiles) return callback(new Error('Tilesource not loaded'));
if (this._nocache) return Source.prototype.getTile.call(this,z,x,y,callback);
var source = this;
this._mbtiles.getTile(z,x,y,function(err, data, headers) {
if (!err) {
if (data) data._cache = 'hit';
return callback(err, data, headers);
}
Source.prototype.getTile.call(source,z,x,y,function(err, data, headers) {
if (data) data._cache = 'miss';
callback(err, data, headers);
if (!err && data) source._mbtiles.putTile(z,x,y,data,function(err){
if (err) console.error(verbose('putTile', err));
});
});
});
};
return CachingSource;
};