itowns
Version:
A JS/WebGL framework for 3D geospatial data visualization
321 lines (274 loc) • 8.44 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.CACHE_POLICIES = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var entry;
/**
* Cache policies for flushing. Those policies can be used when something is
* [set]{@link Cache.set} into the Cache, as the lifetime property.
*
* @typedef {Object} CACHE_POLICIES
*
* @property {number} INFINITE - The entry is never flushed, except when the
* `all` flag is set to `true` when calling {@link Cache.flush}.
* @property {number} TEXTURE - Shortcut for texture resources. Time is 15 minutes.
* @property {number} GEOMETRY - Shortcut for geometry resources. Time is 15 minutes.
* minutes.
*/
var CACHE_POLICIES = {
INFINITE: Infinity,
TEXTURE: 900000,
GEOMETRY: 900000
};
/**
* This is a copy of the Map object, except that it also store a value for last
* time used. This value is used for cache expiration mechanism.
*
* @example
* import Cache, { CACHE_POLICIES } from 'Core/Scheduler/Cache';
*
* const cache = new Cache(CACHE_POLICIES.TEXTURE)
* cache.set({ bar: 1 }, 'foo');
* cache.set({ bar: 32 }, 'foo', 'toto');
*
* cache.get('foo');
*
* cache.delete('foo');
*
* cache.clear();
*
* cache.flush();
*/
exports.CACHE_POLICIES = CACHE_POLICIES;
var Cache = /*#__PURE__*/function () {
/**
* @param {number} [lifetime=CACHE_POLICIES.INFINITE] The cache expiration time for all values.
*/
function Cache() {
var lifetime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : CACHE_POLICIES.INFINITE;
(0, _classCallCheck2["default"])(this, Cache);
this.lifeTime = lifetime;
this.lastTimeFlush = Date.now();
this.data = new Map();
}
/**
* Returns the entry related to the specified key, content in array, from the cache.
* The array contents one to three key.
* The last time used property of the entry is updated to extend the longevity of the
* entry.
*
* @param {string[]|number[]} keyArray key array ([key0, key1, key3])
*
* @return {Object}
*/
(0, _createClass2["default"])(Cache, [{
key: "getByArray",
value: function getByArray(keyArray) {
return this.get(keyArray[0], keyArray[1], keyArray[2]);
}
/**
* Adds or updates an entry with specified keys array ([key0, key1, key3]).
* Caution: it overrides any existing entry already set at this/those key/s.
*
* @param {Object} value to add in cache
* @param {string[]|number[]} keyArray key array ([key0, key1, key3])
*
* @return {Object} the added value
*/
}, {
key: "setByArray",
value: function setByArray(value, keyArray) {
return this.set(value, keyArray[0], keyArray[1], keyArray[2]);
}
/**
* Returns the entry related to the specified key from the cache. The last
* time used property of the entry is updated to extend the longevity of the
* entry.
*
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*
* @return {Object}
*/
}, {
key: "get",
value: function get(key1, key2, key3) {
var entry_1 = this.data.get(key1);
if (entry_1 == undefined) {
return;
}
if (entry_1.lastTimeUsed != undefined) {
entry = entry_1;
} else {
var entry_2 = entry_1.get(key2);
if (entry_2 == undefined) {
return;
}
if (entry_2.lastTimeUsed != undefined) {
entry = entry_2;
} else {
var entry_3 = entry_2.get(key3);
if (entry_3 == undefined) {
return;
}
entry = entry_3;
}
}
if (entry.value) {
entry.lastTimeUsed = Date.now();
return entry.value;
}
}
/**
* Adds or updates an entry with specified keys (up to 3).
* Caution: it overrides any existing entry already set at this/those key/s.
*
*
* @param {Object} value to add in cache
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*
* @return {Object} the added value
*/
}, {
key: "set",
value: function set(value, key1, key2, key3) {
entry = {
value: value,
lastTimeUsed: Date.now()
};
if (key2 == undefined) {
this.data.set(key1, entry);
return value;
}
if (!this.data.get(key1)) {
this.data.set(key1, new Map());
}
var entry_map = this.data.get(key1);
if (key3 == undefined) {
entry_map.set(key2, entry);
return value;
}
if (!entry_map.get(key2)) {
entry_map.set(key2, new Map());
}
entry_map.get(key2).set(key3, entry);
return value;
}
/**
* Deletes the specified entry from the cache.
*
* @param {string|number} key1
* @param {string|number} [key2]
* @param {string|number} [key3]
*/
}, {
key: "delete",
value: function _delete(key1, key2, key3) {
var entry_1 = this.data.get(key1);
if (entry_1 === undefined) {
return;
}
if (entry_1.lastTimeUsed != undefined) {
delete this.data.get(key1);
this.data["delete"](key1);
} else {
var entry_2 = entry_1.get(key2);
if (entry_2 === undefined) {
return;
}
if (entry_2.lastTimeUsed != undefined) {
delete entry_1.get(key2);
entry_1["delete"](key2);
if (entry_1.size == 0) {
this.data["delete"](key1);
}
} else {
var entry_3 = entry_2.get(key3);
if (entry_3 === undefined) {
return;
}
delete entry_2.get(key3);
entry_2["delete"](key3);
if (entry_2.size == 0) {
entry_1["delete"](key2);
if (entry_1.size == 0) {
this.data["delete"](key1);
}
}
}
}
}
/**
* Removes all entries of the cache.
*
*/
}, {
key: "clear",
value: function clear() {
this.data.clear();
}
/**
* Flush the cache: entries that have been present for too long since the
* last time they were used, are removed from the cache. By default, the
* time is the current time, but the interval can be reduced by doing
* something like `Cache.flush(Date.now() - reductionTime)`. If you want to
* clear the whole cache, use {@link Cache.clear} instead.
*
* @param {number} [time=Date.now()]
*/
}, {
key: "flush",
value: function flush() {
var _this = this;
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Date.now();
if (this.lifeTime == CACHE_POLICIES.INFINITE || this.lifeTime > time - this.lastTimeFlush || !this.data.size) {
return;
}
this.lastTimeFlush = Infinity;
this.data.forEach(function (v1, i) {
if (_this.lifeTime < time - v1.lastTimeUsed) {
delete _this.data.get(i);
_this.data["delete"](i);
} else {
v1.forEach(function (v2, j) {
if (_this.lifeTime < time - v2.lastTimeUsed) {
delete v1.get(j);
v1["delete"](j);
} else {
v2.forEach(function (v3, k) {
if (_this.lifeTime < time - v3.lastTimeUsed) {
delete v2.get(k);
v2["delete"](k);
} else {
// Work for the moment because all flushed caches have 3 key!
_this.lastTimeFlush = Math.min(_this.lastTimeFlush, v3.lastTimeUsed);
}
});
if (!v2.size) {
delete v1.get(j);
v1["delete"](j);
}
}
});
if (!v1.size) {
delete _this.data.get(i);
_this.data["delete"](i);
}
}
});
if (this.data.size == 0) {
this.lastTimeFlush = Date.now();
}
}
}]);
return Cache;
}();
var _default = Cache;
exports["default"] = _default;