rxdb
Version:
A local-first realtime NoSQL Database for JavaScript applications - https://rxdb.info/
109 lines (105 loc) • 4.33 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.QueryCache = exports.DEFAULT_UNEXECUTED_LIFETIME = exports.DEFAULT_TRY_TO_KEEP_MAX = exports.COLLECTIONS_WITH_RUNNING_CLEANUP = void 0;
exports.countRxQuerySubscribers = countRxQuerySubscribers;
exports.createQueryCache = createQueryCache;
exports.defaultCacheReplacementPolicyMonad = exports.defaultCacheReplacementPolicy = void 0;
exports.triggerCacheReplacement = triggerCacheReplacement;
exports.uncacheRxQuery = uncacheRxQuery;
var _index = require("./plugins/utils/index.js");
/**
* the query-cache makes sure that on every query-state, exactly one instance can exist
* if you use the same mango-query more then once, it will reuse the first RxQuery
*/
var QueryCache = exports.QueryCache = /*#__PURE__*/function () {
function QueryCache() {
this._map = new Map();
}
var _proto = QueryCache.prototype;
/**
* check if an equal query is in the cache,
* if true, return the cached one,
* if false, save the given one and return it
*/
_proto.getByQuery = function getByQuery(rxQuery) {
var stringRep = rxQuery.toString();
return (0, _index.getFromMapOrCreate)(this._map, stringRep, () => rxQuery);
};
return QueryCache;
}();
function createQueryCache() {
return new QueryCache();
}
function uncacheRxQuery(queryCache, rxQuery) {
rxQuery.uncached = true;
var stringRep = rxQuery.toString();
queryCache._map.delete(stringRep);
}
function countRxQuerySubscribers(rxQuery) {
return rxQuery.refCount$.observers.length;
}
var DEFAULT_TRY_TO_KEEP_MAX = exports.DEFAULT_TRY_TO_KEEP_MAX = 100;
var DEFAULT_UNEXECUTED_LIFETIME = exports.DEFAULT_UNEXECUTED_LIFETIME = 30 * 1000;
/**
* The default cache replacement policy
* See docs-src/query-cache.md to learn how it should work.
* Notice that this runs often and should block the cpu as less as possible
* This is a monad which makes it easier to unit test
*/
var defaultCacheReplacementPolicyMonad = (tryToKeepMax, unExecutedLifetime) => (_collection, queryCache) => {
if (queryCache._map.size < tryToKeepMax) {
return;
}
var minUnExecutedLifetime = (0, _index.now)() - unExecutedLifetime;
var maybeUncache = [];
var queriesInCache = Array.from(queryCache._map.values());
for (var rxQuery of queriesInCache) {
// filter out queries with subscribers
if (countRxQuerySubscribers(rxQuery) > 0) {
continue;
}
// directly uncache queries that never executed and are older than unExecutedLifetime
if (rxQuery._lastEnsureEqual === 0 && rxQuery._creationTime < minUnExecutedLifetime) {
uncacheRxQuery(queryCache, rxQuery);
continue;
}
maybeUncache.push(rxQuery);
}
var mustUncache = maybeUncache.length - tryToKeepMax;
if (mustUncache <= 0) {
return;
}
var sortedByLastUsage = maybeUncache.sort((a, b) => a._lastEnsureEqual - b._lastEnsureEqual);
var toRemove = sortedByLastUsage.slice(0, mustUncache);
toRemove.forEach(rxQuery => uncacheRxQuery(queryCache, rxQuery));
};
exports.defaultCacheReplacementPolicyMonad = defaultCacheReplacementPolicyMonad;
var defaultCacheReplacementPolicy = exports.defaultCacheReplacementPolicy = defaultCacheReplacementPolicyMonad(DEFAULT_TRY_TO_KEEP_MAX, DEFAULT_UNEXECUTED_LIFETIME);
var COLLECTIONS_WITH_RUNNING_CLEANUP = exports.COLLECTIONS_WITH_RUNNING_CLEANUP = new WeakSet();
/**
* Triggers the cache replacement policy after waitTime has passed.
* We do not run this directly because at exactly the time a query is created,
* we need all CPU to minimize latency.
* Also this should not be triggered multiple times when waitTime is still waiting.
*/
function triggerCacheReplacement(rxCollection) {
if (COLLECTIONS_WITH_RUNNING_CLEANUP.has(rxCollection)) {
// already started
return;
}
COLLECTIONS_WITH_RUNNING_CLEANUP.add(rxCollection);
/**
* Do not run directly to not reduce result latency of a new query
*/
(0, _index.nextTick)() // wait at least one tick
.then(() => (0, _index.requestIdlePromise)(200)) // and then wait for the CPU to be idle
.then(() => {
if (!rxCollection.closed) {
rxCollection.cacheReplacementPolicy(rxCollection, rxCollection._queryCache);
}
COLLECTIONS_WITH_RUNNING_CLEANUP.delete(rxCollection);
});
}
//# sourceMappingURL=query-cache.js.map
;