@beenotung/tslib
Version:
utils library in Typescript
77 lines • 2.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemorizePool = exports.memorize = void 0;
const map_map_1 = require("./map-map");
const reflection_1 = require("./reflection");
/* tslint:disable:ban-types */
/**
* @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) {
/* tslint:enable:ban-types */
/* length => ...args */
const cache = new map_map_1.MapMap();
return Object.assign(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);
map.set(last, res);
return res;
}, f.length, f.name), { clear: () => cache.clear() });
}
exports.memorize = memorize;
class MemorizePool {
constructor() {
this.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)) {
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;
//# sourceMappingURL=memorize.js.map