cache-base-debug.js revision d49f394f1b80e68357a4896ef90df98cbd63e909
fb84f9014321c5f33c4682de5661b579fcde318fAndreas GustafssonYUI.add('cache-base', function(Y) {
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews/**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * The Cache utility provides a common configurable interface for components to
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson * cache and retrieve data from a local JavaScript struct.
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson *
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson * @module cache
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrewsvar LANG = Y.Lang,
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrews isDate = Y.Lang.isDate,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrews/**
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrews * Base class for the YUI Cache utility.
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrews * @class Cache
af5073d03288a53b646ec3b807ac25ced64d7879Mark Andrews * @extends Base
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson * @constructor
00124ad0406365d39f4b2d1011ef6a76706e9df0Mark Andrews */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob AusteinCache = function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Cache.superclass.constructor.apply(this, arguments);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein};
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache static properties
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob AusteinY.mix(Cache, {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Class name.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @property NAME
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type String
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @static
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @final
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @value "cache"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews NAME: "cache",
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein ATTRS: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache Attributes
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute max
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Maximum number of entries the Cache can hold.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Set to 0 to turn off caching.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @default 0
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein max: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein value: 0,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein setter: "_setMax"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute size
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Number of entries currently cached.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein size: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein readOnly: true,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein getter: "_getSize"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute uniqueKeys
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Validate uniqueness of stored keys. Default is false and
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * is more performant.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Boolean
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein uniqueKeys: {
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews value: false
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute expires
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Absolute Date when data expires or
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * relative number of milliseconds. Zero disables expiration.
61e1dc26d62c2a0059e3ca7efe2ad0f4a5b8df92Mark Andrews * @type Date | Number
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @default 0
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein expires: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein value: 0,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein validator: function(v) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return Y.Lang.isDate(v) || (Y.Lang.isNumber(v) && v >= 0);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @attribute entries
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Cached entries.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Array
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein readOnly: true,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein getter: "_getEntries"
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob AusteinY.extend(Cache, Y.Base, {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache private properties
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Array of request/response objects indexed chronologically.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @property _entries
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @type Object[]
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @private
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _entries: null,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache private methods
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method initializer
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Internal init() handler.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param config {Object} Config object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @private
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein initializer: function(config) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @event add
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Fired when an entry is added.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade with the following properties:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * </dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @preventable _defAddFn
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.publish("add", {defaultFn: this._defAddFn});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @event flush
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Fired when the cache is flushed.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @preventable _defFlushFn
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.publish("flush", {defaultFn: this._defFlushFn});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @event request
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Fired when an entry is requested from the cache.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade with the following properties:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dt>request (Object)</dt> <dd>The request object.</dd>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * </dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @event retrieve
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Fired when an entry is retrieved from the cache.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade with the following properties:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * </dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Initialize internal values
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this._entries = [];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Cache initialized", "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method destructor
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @description Internal destroy() handler.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @private
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein destructor: function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this._entries = [];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Cache destroyed", "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache protected methods
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Sets max.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _setMax
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _setMax: function(value) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // If the cache is full, make room by removing stalest element (index=0)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var entries = this._entries;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(value > 0) {
61e1dc26d62c2a0059e3ca7efe2ad0f4a5b8df92Mark Andrews if(entries) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein while(entries.length > value) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries.shift();
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein else {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein value = 0;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this._entries = [];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return value;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
75c0816e8295e180f4bc7f10db3d0d880383bc1cMark Andrews /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Gets size.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _getSize
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _getSize: function() {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return this._entries.length;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Gets all entries.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _getEntries
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _getEntries: function() {
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson return this._entries;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Adds entry to cache.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _defAddFn
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade with the following properties:
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * </dl>
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _defAddFn: function(e) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var entries = this._entries,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein max = this.get("max"),
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entry = e.entry;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(this.get("uniqueKeys") && (this.retrieve(e.entry.request))) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries.shift();
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // If the cache at or over capacity, make room by removing stalest element (index=0)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein while(max && entries.length>=max) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries.shift();
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Add entry to cache in the newest position, at the end of the array
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries[entries.length] = entry;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Cached entry: " + Y.dump(entry), "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Flushes cache.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _defFlushFn
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param e {Event.Facade} Event Facade object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _defFlushFn: function(e) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var entries = this._entries,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein details = e.details[0],
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein pos;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //passed an item, flush only that
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(details && LANG.isValue(details.request)) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein pos = this._position(details.request);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(LANG.isValue(pos)) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries.splice(pos,1);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Flushed cache item " + Y.dump(details.request), "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //no item, flush everything
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein else {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this._entries = [];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Cache flushed", "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Default overridable method compares current request with given cache entry.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Returns true if current request matches the cached request, otherwise
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * false. Implementers should override this method to customize the
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * cache-matching algorithm.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _isMatch
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param request {Object} Request object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param entry {Object} Cached entry.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return {Boolean} True if current request matches given cached request, false otherwise.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _isMatch: function(request, entry) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(!entry.expires || new Date() < entry.expires) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return (request === entry.request);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return false;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Returns position of a request in the entries array, otherwise null.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method _position
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param request {Object} Request object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return {Number} Array position if found, null otherwise.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @protected
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein _position: function(request) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // If cache is enabled...
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var entries = this._entries,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein length = entries.length,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein i = length-1;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if((this.get("max") === null) || this.get("max") > 0) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Loop through each cached entry starting from the newest
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein for(; i >= 0; i--) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Execute matching function
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(this._isMatch(request, entries[i])) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return i;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return null;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Cache public methods
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein //
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /////////////////////////////////////////////////////////////////////////////
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Adds a new entry to the cache of the format
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * {request:request, response:response, cached:cached, expires:expires}.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * If cache is full, evicts the stalest entry before adding the new one.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method add
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param request {Object} Request value.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param response {Object} Response value.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein add: function(request, response) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var expires = this.get("expires");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(this.get("initialized") && ((this.get("max") === null) || this.get("max") > 0) &&
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein (LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.fire("add", {entry: {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein request:request,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein response:response,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein cached: new Date(),
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein expires: isDate(expires) ? expires :
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein (expires ? new Date(new Date().getTime() + this.get("expires")) : null)
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein else {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Could not add " + Y.dump(response) + " to cache for " + Y.dump(request), "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Flushes cache.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method flush
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein flush: function(request) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.fire("flush", { request: (LANG.isValue(request) ? request : null) });
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein },
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein /**
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * Retrieves cached object for given request, if available, and refreshes
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * entry in the cache. Returns null if there is no cache match.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein *
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @method retrieve
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @param request {Object} Request object.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein * @return {Object} Cached object with the properties request and response, or null.
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein */
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein retrieve: function(request) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // If cache is enabled...
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein var entries = this._entries,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein length = entries.length,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entry = null,
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein pos;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if((length > 0) && ((this.get("max") === null) || (this.get("max") > 0))) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.fire("request", {request: request});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein pos = this._position(request);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(LANG.isValue(pos)) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entry = entries[pos];
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein this.fire("retrieve", {entry: entry});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Refresh the position of the cache hit
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein if(pos < length-1) {
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Remove element from its original location
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries.splice(pos,1);
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein // Add as newest
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein entries[entries.length] = entry;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Refreshed cache entry: " + Y.dump(entry) +
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein " for request: " + Y.dump(request), "info", "cache");
fb84f9014321c5f33c4682de5661b579fcde318fAndreas Gustafsson }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein Y.log("Retrieved cached response: " + Y.dump(entry) +
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein " for request: " + Y.dump(request), "info", "cache");
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return entry;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein return null;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein }
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob AusteinY.Cache = Cache;
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein}, '@VERSION@' ,{requires:['base']});
60e5e10f8d2e2b0c41e8abad38cacd867caa6ab2Rob Austein