ram64
Version:
Multi-threaded 64bit memory cache database inspired by redis-like features
82 lines (81 loc) • 3.16 kB
JavaScript
;
exports.fn = void 0;
var _functions = require("../functions");
var _shards = require("../shards");
var _tinyLru = _interopRequireDefault(require("tiny-lru"));
var _rand = require("../../util/rand");
var _workerData = require("../worker-data");
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const scanCache = (0, _tinyLru).default(10, 1000 * 60 * 60); // 1hr
const fn = (opts)=>{
const { resumeKey , limit , filterExp , filterFn } = opts.args;
const filterFnHandler = filterFn && (0, _functions).get(filterFn);
let shardIndex = 0;
let iterator;
let iteratorKey;
let maxShardIndex = Number.MAX_SAFE_INTEGER;
if (resumeKey) {
const resumeKeyParts = resumeKey.split(':');
shardIndex = parseInt(resumeKeyParts[1] ?? 0, 10);
iteratorKey = resumeKeyParts[2];
iterator = scanCache.get(iteratorKey);
maxShardIndex = parseInt(resumeKeyParts[3] || Number.MAX_SAFE_INTEGER, 10); // oddly parseInt returns NaN if Infinity is supplied...
}
const maxWorkerShardIndex = maxShardIndex - _workerData.workerData.shardIndex;
let shard = _shards.Shards[shardIndex];
if (!shard) {
throw new Error(`Shard ${shardIndex} does not exist`);
}
if (!iterator) {
iterator = shard.map.keys();
if (!iteratorKey) {
iteratorKey = (0, _rand).randomString();
scanCache.set(iteratorKey, iterator);
}
}
const keys = [];
let key;
let nextResumeKey = void 0;
do {
key = iterator.next().value;
if (key) {
if (!filterFnHandler && !filterExp || filterFnHandler && filterFnHandler.fn(undefined, {
key,
shardIndex: shard.shardIndex
}) || filterExp && filterExp.test(key)) {
keys.push(key);
}
} else {
shardIndex++;
shard = shardIndex <= maxWorkerShardIndex ? _shards.Shards[shardIndex] : undefined;
if (!shard) {
break;
}
iterator = shard.map.keys();
scanCache.delete(iteratorKey); // cleanup old iterator if we know we're done with it
iteratorKey = (0, _rand).randomString();
scanCache.set(iteratorKey, iterator);
nextResumeKey = undefined; // must rebuild
}
}while (shard && keys.length < limit)
if (!nextResumeKey) {
if (shard) {
// exclude maxShardIndex if max int
nextResumeKey = `${_workerData.workerData.workerIndex}:${shardIndex}:${iteratorKey}:${maxShardIndex === Number.MAX_SAFE_INTEGER ? '' : maxShardIndex}`;
} else {
if (_workerData.workerData.workerIndex + 1 < _workerData.workerData.workerCount) {
nextResumeKey = `${_workerData.workerData.workerIndex + 1}:0::${maxShardIndex === Number.MAX_SAFE_INTEGER ? '' : maxShardIndex}`;
} // else we're done, no more resuming to do
}
}
return {
keys,
resumeKey: nextResumeKey
};
};
exports.fn = fn;
//# sourceMappingURL=scan.js.map