2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
8 YUI.add('cache', function(Y) {
11 * The Cache utility provides a common configurable interface for components to
12 * cache and retrieve data from a local JavaScript struct.
19 * Base class for the YUI Cache utility.
21 * @extends Plugin.Base
25 Cache.superclass.constructor.apply(this, arguments);
28 /////////////////////////////////////////////////////////////////////////////
30 // Cache static properties
32 /////////////////////////////////////////////////////////////////////////////
35 * The namespace for the plugin. This will be the property on the host which
36 * references the plugin instance.
60 /////////////////////////////////////////////////////////////////////////////
64 /////////////////////////////////////////////////////////////////////////////
68 * @description Maximum number of entries the Cache can hold.
69 * Set to 0 to turn off caching.
75 validator: function(value) {
76 return (LANG.isNumber(value));
78 setter: function(value) {
79 // If the cache is full, make room by removing stalest element (index=0)
80 var entries = this._entries;
83 while(entries.length > value) {
97 * @description Number of entries currently cached.
103 return this._entries.length;
108 * @attribute uniqueKeys
109 * @description Validate uniqueness of stored keys. Default is false and
110 * is more performant.
115 validator: function(value) {
116 return (LANG.isBoolean(value));
122 * @description Cached entries.
128 return this._entries;
134 Y.extend(Cache, Y.Plugin.Base, {
135 /////////////////////////////////////////////////////////////////////////////
137 // Cache private properties
139 /////////////////////////////////////////////////////////////////////////////
142 * Array of request/response objects indexed chronologically.
150 /////////////////////////////////////////////////////////////////////////////
152 // Cache private methods
154 /////////////////////////////////////////////////////////////////////////////
157 * @method initializer
158 * @description Internal init() handler.
159 * @param config {Object} Config object.
162 initializer: function(config) {
166 * @description Fired when an entry is added.
167 * @param e {Event.Facade} Event Facade with the following properties:
169 * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
171 * @preventable _defAddFn
173 this.publish("add", {defaultFn: this._defAddFn});
177 * @description Fired when the cache is flushed.
178 * @param e {Event.Facade} Event Facade object.
179 * @preventable _defFlushFn
181 this.publish("flush", {defaultFn: this._defFlushFn});
185 * @description Fired when an entry is requested from the cache.
186 * @param e {Event.Facade} Event Facade with the following properties:
188 * <dt>request (Object)</dt> <dd>The request object.</dd>
194 * @description Fired when an entry is retrieved from the cache.
195 * @param e {Event.Facade} Event Facade with the following properties:
197 * <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>
201 // Initialize internal values
207 * @description Internal destroy() handler.
210 destructor: function() {
211 this._entries = null;
214 /////////////////////////////////////////////////////////////////////////////
216 // Cache protected methods
218 /////////////////////////////////////////////////////////////////////////////
221 * Adds entry to cache.
224 * @param e {Event.Facade} Event Facade with the following properties:
226 * <dt>entry (Object)</dt> <dd>The cached entry.</dd>
230 _defAddFn: function(e) {
231 var entries = this._entries,
232 max = this.get("max"),
235 if(this.get("uniqueKeys") && (this.retrieve(e.entry.request))) {
240 // If the cache at or over capacity, make room by removing stalest element (index=0)
241 while(entries.length>=max) {
245 // Add entry to cache in the newest position, at the end of the array
246 entries[entries.length] = entry;
252 * @method _defFlushFn
253 * @param e {Event.Facade} Event Facade object.
256 _defFlushFn: function(e) {
261 * Default overridable method compares current request with given cache entry.
262 * Returns true if current request matches the cached request, otherwise
263 * false. Implementers should override this method to customize the
264 * cache-matching algorithm.
267 * @param request {Object} Request object.
268 * @param entry {Object} Cached entry.
269 * @return {Boolean} True if current request matches given cached request, false otherwise.
272 _isMatch: function(request, entry) {
273 return (request === entry.request);
276 /////////////////////////////////////////////////////////////////////////////
278 // Cache public methods
280 /////////////////////////////////////////////////////////////////////////////
283 * Adds a new entry to the cache of the format
284 * {request:request, response:response, payload:payload}.
285 * If cache is full, evicts the stalest entry before adding the new one.
288 * @param request {Object} Request value.
289 * @param response {Object} Response value.
290 * @param payload {Object} (optional) Arbitrary data payload.
292 add: function(request, response, payload) {
293 if(this.get("entries") && (this.get("max")>0) &&
294 (LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {
295 this.fire("add", {entry: {request:request, response:response, payload:payload}});
311 * Retrieves cached entry for given request, if available, and refreshes
312 * entry in the cache. Returns null if there is no cache match.
315 * @param request {Object} Request object.
316 * @return {Object} Cached entry object with the properties request, response, and payload, or null.
318 retrieve: function(request) {
319 // If cache is enabled...
320 var entries = this._entries,
321 length = entries.length,
325 if((this.get("max") > 0) && (length > 0)) {
326 this.fire("request", {request: request});
328 // Loop through each cached entry starting from the newest
332 // Execute matching function
333 if(this._isMatch(request, entry)) {
334 this.fire("retrieve", {entry: entry});
336 // Refresh the position of the cache hit
338 // Remove element from its original location
341 entries[entries.length] = entry;
357 }, '3.0.0' ,{requires:['plugin']});