Path: blob/trunk/third_party/closure/goog/memoize/memoize.js
4167 views
/**1* @license2* Copyright The Closure Library Authors.3* SPDX-License-Identifier: Apache-2.04*/56/**7* @fileoverview Tool for caching the result of expensive deterministic8* functions.9*10* @see http://en.wikipedia.org/wiki/Memoization11*/1213goog.module('goog.memoize');14goog.module.declareLegacyNamespace();1516const reflect = goog.require('goog.reflect');1718/**19* Note that when using the WeakMap polyfill users may run into issues20* where memoize is unable to store a cache properly (as the polyfill tries to21* store the values on the key object as properties.). The workaround is to not22* memoize onto a sealed context if the code needs to run in browsers where23* WeakMap is not available (IE<=10 as an example).24* @type {!WeakMap<!Object, !Object>}25*/26const MODULE_LOCAL_CACHE = new WeakMap();2728/**29* Decorator around functions that caches the inner function's return values.30*31* To cache parameterless functions, see goog.functions.cacheReturnValue.32*33* @param {Function} f The function to wrap. Its return value may only depend34* on its arguments and 'this' context. There may be further restrictions35* on the arguments depending on the capabilities of the serializer used.36* @param {function(number, !IArrayLike<?>): string=} serializer A function to37* serialize f's arguments. It must have the same signature as38* goog.memoize.simpleSerializer. It defaults to that function.39* @return {!Function} The wrapped function.40*/41function memoize(f, serializer = simpleSerializer) {42const uidF = goog.getUid(f);43const keyFn = ([that, ...args]) => serializer(uidF, args);44const valueFn = ([that, ...args]) => f.apply(that, args);4546/**47* @this {Object} The object whose function is being wrapped.48* @param {...*} args49* @return {?} the return value of the original function.50*/51const memoizedFn = function(...args) {52if (memoize.ENABLE_MEMOIZE) {53const cacheKey = this || goog.global;54let cache = MODULE_LOCAL_CACHE.get(cacheKey);55if (!cache) {56cache = {};57MODULE_LOCAL_CACHE.set(cacheKey, cache);58}59return reflect.cache(cache, [this, ...args], valueFn, keyFn);60} else {61return f.apply(this, args);62}63};64return memoizedFn;65}66exports = memoize;6768/**69* @define {boolean} Flag to disable memoization in unit tests.70*/71memoize.ENABLE_MEMOIZE = goog.define('goog.memoize.ENABLE_MEMOIZE', true);727374/**75* Clears the memoization cache on the given object.76* @param {?Object} cacheOwner The owner of the cache.77*/78const clearCache = function(cacheOwner) {79MODULE_LOCAL_CACHE.set(cacheOwner || goog.global, {});80};81exports.clearCache = clearCache;828384/**85* Simple and fast argument serializer function for goog.memoize.86* Supports string, number, boolean, null and undefined arguments. Doesn't87* support \x0B characters in the strings.88* @param {number} functionUid Unique identifier of the function whose result89* is cached.90* @param {!IArrayLike<?>} args The arguments that the function to memoize is91* called with. Note: it is an array-like object, because it supports92* indexing and has the length property.93* @return {string} The list of arguments with type information concatenated94* with the functionUid argument, serialized as \x0B-separated string.95*/96const simpleSerializer = function(functionUid, args) {97const context = [functionUid];98for (let i = args.length - 1; i >= 0; --i) {99context.push(typeof args[i], args[i]);100}101return context.join('\x0B');102};103exports.simpleSerializer = simpleSerializer;104105106