Skip to content

Instantly share code, notes, and snippets.

@joedski
Created July 16, 2017 23:35
Show Gist options
  • Save joedski/ddc97104551d28720c9fed5ed01cc9a7 to your computer and use it in GitHub Desktop.
Save joedski/ddc97104551d28720c9fed5ed01cc9a7 to your computer and use it in GitHub Desktop.
The simplest case, which doesn't allow you to use existing memoizers, though you can use their stores if they expose that.
// Simple single-value store.
// Setting a KV pair overwrites the last.
// Follows a get/set/has interface similar to Maps.
function singleValueStore() {
let key;
let value;
let isSet = false;
function get(givenKey) {
if (!isSet) return undefined;
if (givenKey === key) return value;
return undefined;
}
function set(givenKey, givenValue) {
isSet = true;
key = givenKey;
value = givenValue;
}
function has(givenKey) {
if (!isSet) return false;
return givenKey === key;
}
return { get, set, has };
}
// Saves a function and args, deferring application with a thunk.
// The result is cached the first time and returned on subsequent calls.
function memoizeApplication(fn, args) {
let called = false;
let value;
return function thunk() {
if (!called) {
called = true;
value = fn(...args);
}
return value;
};
}
// This differs from my other versions by dealing directly with stores
// rather than other memoize functions.
function createTieredMemoizer(options = {}) {
const {
stores = [],
defaultStore = singleValueStore,
} = options;
return function memoize(fn) {
function getNewRecordFor(n) {
return {
store: (stores[n] || defaultStore)(),
// We can't eagerly put anything here because we don't know the args.
result: null,
};
}
const rootRecord = getNewRecordFor(0);
return function memoizedFn(...args) {
const record = args.reduce(
(nextRecord, arg, i) => {
if (!nextRecord.store.has(arg)) {
nextRecord.store.set(arg, getNewRecordFor(i + 1));
}
return nextRecord.store.get(arg);
},
rootRecord
);
if (!record.result) {
record.result = memoizeApplication(fn, args);
}
return record.result();
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment