@beenotung/tslib
Version:
utils library in Typescript
90 lines (89 loc) • 2.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemorizePool = void 0;
exports.memorize = memorize;
const map_map_1 = require("./map-map");
const reflection_1 = require("./reflection");
/**
* @description support any arguments length, any data type arguments
* do not works for self-recursive functions
* unless it is wrapped when being constructed
*
* Example that works:
*
* const q = memorize((n: number) => n < 2 ? 1 : q(n - 1) + q(n - 2));
*
* Example that do not works:
*
* let f = (n: number) => n < 2 ? 1 : f(n - 1) + f(n - 2);
* f = memorize(f);
*
* */
function memorize(f) {
/* length => ...args */
const cache = new map_map_1.MapMap();
return Object.assign((0, reflection_1.wrapFunction)(function () {
let map = cache.getMap(arguments.length);
for (let i = arguments.length - 1; i > 0; i--) {
map = map.getMap(arguments[i]);
}
const last = arguments[0];
if (map.has(last)) {
return map.get(last);
}
const res = f.apply(null, arguments);
if (res instanceof Promise) {
res.catch(_error => {
map.delete(last);
});
}
map.set(last, res);
return res;
}, f.length, f.name), {
clear: () => cache.clear(),
cache,
remove: function (..._args) {
let map = cache.getMap(arguments.length);
for (let i = arguments.length - 1; i > 0; i--) {
map = map.getMap(arguments[i]);
}
const last = arguments[0];
map.delete(last);
},
});
}
class MemorizePool {
cache = new map_map_1.MapMap();
get(args) {
const map = this.getLastMap(args);
const last = args[0];
if (map.has(last)) {
return [map.get(last)];
}
else {
return undefined;
}
}
set(args, res) {
this.getLastMap(args).set(args[0], res);
}
getOrCalc(args, f) {
const map = this.getLastMap(args);
const last = args[0];
if (map.has(last)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return map.get(last);
}
const res = f();
map.set(last, res);
return res;
}
getLastMap(args) {
let map = this.cache.getMap(args.length);
for (let i = args.length - 1; i > 0; i--) {
map = map.getMap(args[i]);
}
return map;
}
}
exports.MemorizePool = MemorizePool;