aboutsummaryrefslogtreecommitdiffstats
path: root/packages/vold-utils/lib/memoize.js
diff options
context:
space:
mode:
authorNik Nyby <nikolas@gnu.org>2015-01-17 17:12:36 -0500
committerNik Nyby <nikolas@gnu.org>2015-01-17 17:12:36 -0500
commitada88090ead2c3b9d0804794c5f20f9b24d1c2b1 (patch)
tree2838a7eee6c5d74094216acebd86915e0ea1de42 /packages/vold-utils/lib/memoize.js
downloadlibrejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.tar.lz
librejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.tar.xz
librejsxul-ada88090ead2c3b9d0804794c5f20f9b24d1c2b1.zip
Import to new git repository
The old repository was using almost 100mb of space because of all the unnecessary files in the history. So I've imported the code to a new git repository. Unfortunately the history isn't viewable from this repository anymore. To see what happened with LibreJS before 2015, see the old Bazaar repo here: http://bzr.savannah.gnu.org/lh/librejs/
Diffstat (limited to 'packages/vold-utils/lib/memoize.js')
-rw-r--r--packages/vold-utils/lib/memoize.js131
1 files changed, 131 insertions, 0 deletions
diff --git a/packages/vold-utils/lib/memoize.js b/packages/vold-utils/lib/memoize.js
new file mode 100644
index 0000000..73bb4fc
--- /dev/null
+++ b/packages/vold-utils/lib/memoize.js
@@ -0,0 +1,131 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MIT/X11 License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Contributor(s):
+ * Nils Maier <MaierMan@web.de>
+ * Erik Vold <erikvvold@gmail.com>
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+"use strict";
+
+/**
+ * Decorate a function with a memoization wrapper, with a limited-size cache
+ * to reduce peak memory utilization.
+ *
+ * The memoized function may have any number of arguments, but they must be
+ * be serializable. It's safest to use this only on functions that accept
+ * primitives.
+ *
+ * A memoized function is not thread-safe, but so is JS, nor re-entrant-safe!
+ *
+ * @usage var foo = Scriptish_memoize(function foo(arg1, arg2) { ... complex operation ... });
+ * @param {Function} func The function to be memoized
+ * @param {Number} limit Optional. Cache size (default: 100)
+ * @param {Number} num_args Options. Number of arguments the function expects (default: func.length)
+ * @return {Function} Memoized function
+ */
+exports.memoize = function memoize(func, limit, num_args) {
+ limit = limit || 100;
+ num_args = num_args || func.length;
+
+ var cache = Object.create(null);
+ var keylist = [];
+ var args = [];
+ var key, result;
+
+ switch (num_args) {
+ case 0:
+ throw new Error("memoize does not support functions without arguments");
+ case 1:
+ return function memoize_one_arg(a) {
+ key = a.toString();
+
+ if (key in cache)
+ return cache[key];
+
+ result = func.call(null, a);
+ cache[key] = result;
+ if (keylist.push(key) > limit)
+ delete cache[keylist.shift()];
+ return result;
+ };
+ case 2:
+ return function memoize_two_args(a, b) {
+ args[0] = a; args[1] = b;
+ key = JSON.stringify(args);
+ args.length = 0;
+
+ if (key in cache)
+ return cache[key];
+
+ var result = func.call(null, a, b);
+ cache[key] = result;
+ if (keylist.push(key) > limit)
+ delete cache[keylist.shift()];
+ return result;
+ };
+ case 3:
+ return function memoize_three_args(a, b, c) {
+ args[0] = a; args[1] = b; args[2] = c;
+ key = JSON.stringify(args);
+ args.length = 0;
+
+ if (key in cache)
+ return cache[key];
+
+ var result = func.call(null, a, b, c);
+ cache[key] = result;
+ if (keylist.push(key) > limit)
+ delete cache[keylist.shift()];
+ return result;
+ };
+
+ case 4:
+ return function memoize_four_args(a, b, c, d) {
+ args[0] = a; args[1] = b; args[2] = c; args[3] = d;
+ key = JSON.stringify(args);
+ args.length = 0;
+
+ if (key in cache)
+ return cache[key];
+
+ var result = func.call(null, a, b, c, d);
+ cache[key] = result;
+ if (keylist.push(key) > limit)
+ delete cache[keylist.shift()];
+ return result;
+ };
+
+ default:
+ return function() {
+ var key = JSON.stringify(arguments);
+ if (key in cache)
+ return cache[key];
+
+ var result = func.apply(null, arguments);
+ cache[key] = result;
+ if (keylist.push(key) > limit)
+ delete cache[keylist.shift()];
+ return result;
+ };
+ }
+}