simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

function.js (3758B)


      1 "use strict";
      2 
      3 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
      4 
      5 Object.defineProperty(exports, "__esModule", {
      6   value: true
      7 });
      8 exports.maxArgumentCount = maxArgumentCount;
      9 exports.memoize = memoize;
     10 exports.memoizeCompare = memoizeCompare;
     11 
     12 var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
     13 
     14 var _lruQueue = require("./lruQueue.js");
     15 
     16 // function utils
     17 
     18 /**
     19  * Memoize a given function by caching the computed result.
     20  * The cache of a memoized function can be cleared by deleting the `cache`
     21  * property of the function.
     22  *
     23  * @param {function} fn                     The function to be memoized.
     24  *                                          Must be a pure function.
     25  * @param {Object} [options]
     26  * @param {function(args: Array): string} [options.hasher]
     27  *    A custom hash builder. Is JSON.stringify by default.
     28  * @param {number | undefined} [options.limit]
     29  *    Maximum number of values that may be cached. Undefined indicates
     30  *    unlimited (default)
     31  * @return {function}                       Returns the memoized function
     32  */
     33 function memoize(fn) {
     34   var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
     35       hasher = _ref.hasher,
     36       limit = _ref.limit;
     37 
     38   limit = limit == null ? Number.POSITIVE_INFINITY : limit;
     39   hasher = hasher == null ? JSON.stringify : hasher;
     40   return function memoize() {
     41     if ((0, _typeof2.default)(memoize.cache) !== 'object') {
     42       memoize.cache = {
     43         values: new Map(),
     44         lru: (0, _lruQueue.lruQueue)(limit || Number.POSITIVE_INFINITY)
     45       };
     46     }
     47 
     48     var args = [];
     49 
     50     for (var i = 0; i < arguments.length; i++) {
     51       args[i] = arguments[i];
     52     }
     53 
     54     var hash = hasher(args);
     55 
     56     if (memoize.cache.values.has(hash)) {
     57       memoize.cache.lru.hit(hash);
     58       return memoize.cache.values.get(hash);
     59     }
     60 
     61     var newVal = fn.apply(fn, args);
     62     memoize.cache.values.set(hash, newVal);
     63     memoize.cache.values.delete(memoize.cache.lru.hit(hash));
     64     return newVal;
     65   };
     66 }
     67 /**
     68  * Memoize a given function by caching all results and the arguments,
     69  * and comparing against the arguments of previous results before
     70  * executing again.
     71  * This is less performant than `memoize` which calculates a hash,
     72  * which is very fast to compare. Use `memoizeCompare` only when it is
     73  * not possible to create a unique serializable hash from the function
     74  * arguments.
     75  * The isEqual function must compare two sets of arguments
     76  * and return true when equal (can be a deep equality check for example).
     77  * @param {function} fn
     78  * @param {function(a: *, b: *) : boolean} isEqual
     79  * @returns {function}
     80  */
     81 
     82 
     83 function memoizeCompare(fn, isEqual) {
     84   var memoize = function memoize() {
     85     var args = [];
     86 
     87     for (var i = 0; i < arguments.length; i++) {
     88       args[i] = arguments[i];
     89     }
     90 
     91     for (var c = 0; c < memoize.cache.length; c++) {
     92       var cached = memoize.cache[c];
     93 
     94       if (isEqual(args, cached.args)) {
     95         // TODO: move this cache entry to the top so recently used entries move up?
     96         return cached.res;
     97       }
     98     }
     99 
    100     var res = fn.apply(fn, args);
    101     memoize.cache.unshift({
    102       args: args,
    103       res: res
    104     });
    105     return res;
    106   };
    107 
    108   memoize.cache = [];
    109   return memoize;
    110 }
    111 /**
    112  * Find the maximum number of arguments expected by a typed function.
    113  * @param {function} fn   A typed function
    114  * @return {number} Returns the maximum number of expected arguments.
    115  *                  Returns -1 when no signatures where found on the function.
    116  */
    117 
    118 
    119 function maxArgumentCount(fn) {
    120   return Object.keys(fn.signatures || {}).reduce(function (args, signature) {
    121     var count = (signature.match(/,/g) || []).length + 1;
    122     return Math.max(args, count);
    123   }, -1);
    124 }