UNPKG

trie-memoize

Version:

A memoization algorithm in which each function argument represents a new key, creating a trie of caches as defined by the array in your first argument.

89 lines (75 loc) 1.77 kB
const createCache = obj => { try { // @ts-ignore return new obj(); } catch (e) { const cache = {}; return { set(k, v) { cache[k] = v; }, get(k) { return cache[k]; } }; } }; const memo = constructors => { const depth = constructors.length, baseCache = createCache(constructors[0]); let base; let map; let i; let node; const one = depth === 1; // quicker access for one and two-argument functions const g1 = args => (base = baseCache.get(args[0])) === void 0 || one ? base : base.get(args[1]); const s1 = (args, value) => { if (one) baseCache.set(args[0], value);else { if ((base = baseCache.get(args[0])) === void 0) { map = createCache(constructors[1]); map.set(args[1], value); baseCache.set(args[0], map); } else { base.set(args[1], value); } } return value; }; const g2 = args => { node = baseCache; for (i = 0; i < depth; i++) if ((node = node.get(args[i])) === void 0) return; return node; }; const s2 = (args, value) => { node = baseCache; for (i = 0; i < depth - 1; i++) { if ((map = node.get(args[i])) === void 0) { map = createCache(constructors[i + 1]); node.set(args[i], map); node = map; } else { node = map; } } node.set(args[depth - 1], value); return value; }; return depth < 3 ? { g: g1, s: s1 } : { g: g2, s: s2 }; }; const memoize = (mapConstructors, fn) => { let item; const { g, s } = memo(mapConstructors); return function () { return (item = g(arguments)) === void 0 ? s(arguments, fn.apply(null, arguments)) : item; }; }; export default memoize;