UNPKG

@beenotung/tslib

Version:
90 lines (89 loc) 2.61 kB
"use strict"; 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;