From 2554f4ab01ee327886426e7deee23c7690fec43e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Mar 2015 16:26:39 -0700 Subject: [PATCH] [Core] Add model cache Add a cache for domain object models which prevents unnecessary reload of those objects. WTD-1033. --- bundles.json | 1 - platform/core/bundle.json | 5 ++ .../core/src/models/CachingModelDecorator.js | 84 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 platform/core/src/models/CachingModelDecorator.js diff --git a/bundles.json b/bundles.json index 8da51c03ac..2d900e8529 100644 --- a/bundles.json +++ b/bundles.json @@ -12,7 +12,6 @@ "platform/features/plot", "platform/features/scrolling", "platform/forms", - "platform/persistence/cache", "platform/persistence/queue", "platform/persistence/elastic", diff --git a/platform/core/bundle.json b/platform/core/bundle.json index 5689d824db..5a2727eb75 100644 --- a/platform/core/bundle.json +++ b/platform/core/bundle.json @@ -65,6 +65,11 @@ "implementation": "models/PersistedModelProvider.js", "depends": [ "persistenceService", "$q", "PERSISTENCE_SPACE" ] }, + { + "provides": "modelService", + "type": "decorator", + "implementation": "models/CachingModelDecorator.js" + }, { "provides": "typeService", "type": "provider", diff --git a/platform/core/src/models/CachingModelDecorator.js b/platform/core/src/models/CachingModelDecorator.js new file mode 100644 index 0000000000..e5dbf22643 --- /dev/null +++ b/platform/core/src/models/CachingModelDecorator.js @@ -0,0 +1,84 @@ +/*global define*/ + +define( + [], + function () { + "use strict"; + + /** + * The caching model decorator maintains a cache of loaded domain + * object models, and ensures that duplicate models for the same + * object are not provided. + * @constructor + */ + function CachingModelDecorator(modelService) { + var cache = {}, + cached = {}; + + // Fast-resolving promise + function fastPromise(value) { + return (value || {}).then ? value : { + then: function (callback) { + return fastPromise(callback(value)); + } + }; + } + + // Store this model in the cache + function cacheModel(id, model) { + cache[id] = model; + cached[id] = true; + } + + // Check if an id is not in cache, for lookup filtering + function notCached(id) { + return !cached[id]; + } + + // Store the provided models in our cache + function cacheAll(models) { + Object.keys(models).forEach(function (id) { + cacheModel(id, models[id]); + }); + } + + // Expose the cache (for promise chaining) + function giveCache() { + return cache; + } + + return { + /** + * Get models for these specified string identifiers. + * These will be given as an object containing keys + * and values, where keys are object identifiers and + * values are models. + * This result may contain either a subset or a + * superset of the total objects. + * + * @param {Array} ids the string identifiers for + * models of interest. + * @returns {Promise} a promise for an object + * containing key-value pairs, where keys are + * ids and values are models + * @method + */ + getModels: function (ids) { + var neededIds = ids.filter(notCached); + + // Look up if we have unknown IDs + if (neededIds.length > 0) { + return modelService.getModels(neededIds) + .then(cacheAll) + .then(giveCache); + } + + // Otherwise, just expose the cache directly + return fastPromise(cache); + } + }; + } + + return CachingModelDecorator; + } +); \ No newline at end of file