Jon Atkins 600fe1f91c experimental: JSON encode the data stored in the cache
in theory, keeping the javascript objects directly in the cache is a good thing. any instances of, for example, portals on the map, will share the data objects with those in the cache, limiting the overheads for cached items in use
however, in practice
- relatively large and complex data structures for cached data. and as some items expired from the cache may have data in live portals, etc, complex for garbage collection to clean up. strings, on the other hand - one single object to clean, zero references from anything else
- the cache is used as an alternative to network requests. therefore the extra time to encode/parse the strings is no real issue
- lower memory overheads? it's liekly a single string is more efficient on RAM use, even taking into account that some objects will be both encoded in the string, and duplicated in live entities on the map

time will tell if this is better or worse than direct object storage...
2015-02-21 23:32:57 +00:00

91 lines
2.7 KiB
JavaScript

// MAP DATA CACHE ///////////////////////////////////
// cache for map data tiles.
window.DataCache = function() {
this.REQUEST_CACHE_FRESH_AGE = 3*60; // if younger than this, use data in the cache rather than fetching from the server
this.REQUEST_CACHE_MAX_AGE = 15*60; // maximum cache age. entries are deleted from the cache after this time
if (L.Browser.mobile) {
// on mobile devices, smaller cache size
this.REQUEST_CACHE_MAX_SIZE = 300; // if more than this many entries, expire early
} else {
// but on desktop, allow more
this.REQUEST_CACHE_MAX_SIZE = 1000; // if more than this many entries, expire early
}
this._cache = {};
this._interval = undefined;
}
window.DataCache.prototype.store = function(qk,data,freshTime) {
// fixme? common behaviour for objects is that properties are kept in the order they're added
// this is handy, as it allows easy retrieval of the oldest entries for expiring
// however, this is not guaranteed by the standards, but all our supported browsers work this way
delete this._cache[qk];
var time = new Date().getTime();
if (freshTime===undefined) freshTime = this.REQUEST_CACHE_FRESH_AGE*1000;
var expire = time + freshTime;
this._cache[qk] = { time: time, expire: expire, data: JSON.stringify(data) };
}
window.DataCache.prototype.get = function(qk) {
if (qk in this._cache) return JSON.parse(this._cache[qk].data);
else return undefined;
}
window.DataCache.prototype.getTime = function(qk) {
if (qk in this._cache) return this._cache[qk].time;
else return 0;
}
window.DataCache.prototype.isFresh = function(qk) {
if (qk in this._cache) {
var d = new Date();
var t = d.getTime();
if (this._cache[qk].expire >= t) return true;
else return false;
}
return undefined;
}
window.DataCache.prototype.startExpireInterval = function(period) {
if (this._interval === undefined) {
var savedContext = this;
this._interval = setInterval (function() { savedContext.runExpire(); }, period*1000);
}
}
window.DataCache.prototype.stopExpireInterval = function() {
if (this._interval !== undefined) {
stopInterval (this._interval);
this._interval = undefined;
}
}
window.DataCache.prototype.runExpire = function() {
var d = new Date();
var t = d.getTime()-this.REQUEST_CACHE_MAX_AGE*1000;
var cacheSize = Object.keys(this._cache).length;
for(var qk in this._cache) {
// fixme? our MAX_SIZE test here assumes we're processing the oldest first. this relies
// on looping over object properties in the order they were added. this is true in most browsers,
// but is not a requirement of the standards
if (cacheSize > this.REQUEST_CACHE_MAX_SIZE || this._cache[qk].time < t) {
delete this._cache[qk];
cacheSize--;
}
}
}