UNPKG

flexmonster-mongo-connector

Version:

Custom data source API implementation for MongoDB

114 lines 4.42 kB
"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