flexmonster-mongo-connector
Version:
Custom data source API implementation for MongoDB
114 lines • 4.42 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalDataCache = void 0;
const HashGenerator_1 = require("../../utils/HashGenerator");
class LocalDataCache {
constructor(cacheStrategie, config) {
this._cache = null;
this.timeToLive = 0;
this._cacheSizeLimit = 0;
this._currentCacheSize = 0;
this._garbageCollectingCoefficient = 0.6;
this.garbageItemsComparator = (a, b) => {
const aScore = this.getGarbageItemScore(a);
const bScore = this.getGarbageItemScore(b);
return aScore - bScore;
};
this._cache = new Map();
this._cacheStrategie = cacheStrategie;
this.timeToLive = config.cacheTimeToLive;
this._cacheSizeLimit = config.cacheMemoryLimit * 1024 * 1024;
this._currentCacheSize = 0;
}
setTimeToLive(minutes) {
if (minutes < 0)
return;
this.timeToLive = minutes;
}
getCache(key) {
if (key == null)
throw new Error("Null key exception");
const keyHash = this.getCacheKey(key);
let cachedDataObject = this._cache.get(keyHash);
if (typeof cachedDataObject !== "undefined" && this._cacheStrategie.isCacheStaled(cachedDataObject, this.timeToLive)) {
cachedDataObject = undefined;
this.removeFromCache(key);
}
return typeof cachedDataObject === "undefined" ? undefined : cachedDataObject.data;
}
removeFromCache(key) {
if (key == null)
throw new Error("Null key exception");
const keyHash = this.getCacheKey(key);
const cachedItem = this._cache.get(keyHash);
if (typeof cachedItem === "undefined")
return;
this._removeFromCache(keyHash);
this._currentCacheSize -= cachedItem.dataMemorySize;
cachedItem.data = null;
return;
}
_removeFromCache(keyHash) {
this._cache.delete(keyHash);
}
setCache(key, data) {
const keyHash = this.getCacheKey(key);
this._cache.set(keyHash, {
data: data,
timeStamp: new Date().getTime(),
computationTime: data.computationTime,
dataMemorySize: data.dataMemorySize
});
this._currentCacheSize += data.dataMemorySize;
if (this._cacheSizeLimit > 0 && this._currentCacheSize > this._cacheSizeLimit)
this.collectGabbage();
}
collectGabbage() {
const entries = this._cache.entries();
let entriesList = [];
for (const entry of entries) {
entriesList.push({
key: entry[0],
timeStamp: entry[1].timeStamp,
computationTime: entry[1].computationTime,
dataMemorySize: entry[1].dataMemorySize,
isCacheStaled: this._cacheStrategie.isCacheStaled(entry[1], this.timeToLive)
});
}
entriesList.sort(this.garbageItemsComparator);
let garbageCollectingItem = null;
while (this._cacheSizeLimit * this._garbageCollectingCoefficient <= this._currentCacheSize) {
garbageCollectingItem = entriesList.shift();
this._removeFromCache(garbageCollectingItem.key);
}
entriesList = null;
}
getGarbageItemScore(item) {
if (item.isCacheStaled)
return cacheScoreMetrics.StaledCache;
return item.computationTime;
}
setCacheStrategie(cacheStrategie) {
if (cacheStrategie == null)
return;
this._cacheStrategie = cacheStrategie;
}
clearCache() {
this._cache.clear();
this._currentCacheSize = 0;
}
getCacheKey(objectKey) {
if (objectKey == null)
throw new Error("Null cache object key exception");
const objectKeyString = JSON.stringify(objectKey.clientQuery) + objectKey.databaseName + objectKey.index;
return HashGenerator_1.HashGenerator.createHashFromString(objectKeyString);
}
getCacheMemoryStatus() {
return `Current cache size: ${(this._currentCacheSize / (1024 * 1024)).toFixed(2)} MB`;
}
}
exports.LocalDataCache = LocalDataCache;
const cacheScoreMetrics = {
StaledCache: -300
};
//# sourceMappingURL=LocalDataCache.js.map