2
YUI 3.13.0 (build 508226d)
3
Copyright 2013 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
8
YUI.add('cache-base', function (Y, NAME) {
11
* The Cache utility provides a common configurable interface for components to
12
* cache and retrieve data from a local JavaScript struct.
19
* Provides the base class for the YUI Cache utility.
21
* @submodule cache-base
24
isDate = Y.Lang.isDate,
27
* Base class for the YUI Cache utility.
33
Cache.superclass.constructor.apply(this, arguments);
36
/////////////////////////////////////////////////////////////////////////////
38
// Cache static properties
40
/////////////////////////////////////////////////////////////////////////////
55
/////////////////////////////////////////////////////////////////////////////
59
/////////////////////////////////////////////////////////////////////////////
63
* @description Maximum number of entries the Cache can hold.
64
* Set to 0 to turn off caching.
75
* @description Number of entries currently cached.
84
* @attribute uniqueKeys
85
* @description Validate uniqueness of stored keys. Default is false and
95
* @description Absolute Date when data expires or
96
* relative number of milliseconds. Zero disables expiration.
102
validator: function(v) {
103
return Y.Lang.isDate(v) || (Y.Lang.isNumber(v) && v >= 0);
109
* @description Cached entries.
114
getter: "_getEntries"
119
Y.extend(Cache, Y.Base, {
120
/////////////////////////////////////////////////////////////////////////////
122
// Cache private properties
124
/////////////////////////////////////////////////////////////////////////////
127
* Array of request/response objects indexed chronologically.
135
/////////////////////////////////////////////////////////////////////////////
137
// Cache private methods
139
/////////////////////////////////////////////////////////////////////////////
142
* @method initializer
143
* @description Internal init() handler.
144
* @param config {Object} Config object.
147
initializer: function(config) {
151
* @description Fired when an entry is added.
152
* @param e {Event.Facade} Event Facade with the following properties:
154
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
156
* @preventable _defAddFn
158
this.publish("add", {defaultFn: this._defAddFn});
162
* @description Fired when the cache is flushed.
163
* @param e {Event.Facade} Event Facade object.
164
* @preventable _defFlushFn
166
this.publish("flush", {defaultFn: this._defFlushFn});
170
* @description Fired when an entry is requested from the cache.
171
* @param e {Event.Facade} Event Facade with the following properties:
173
* <dt>request (Object)</dt> <dd>The request object.</dd>
179
* @description Fired when an entry is retrieved from the cache.
180
* @param e {Event.Facade} Event Facade with the following properties:
182
* <dt>entry (Object)</dt> <dd>The retrieved entry.</dd>
186
// Initialize internal values
192
* @description Internal destroy() handler.
195
destructor: function() {
199
/////////////////////////////////////////////////////////////////////////////
201
// Cache protected methods
203
/////////////////////////////////////////////////////////////////////////////
211
_setMax: function(value) {
212
// If the cache is full, make room by removing stalest element (index=0)
213
var entries = this._entries;
216
while(entries.length > value) {
234
_getSize: function() {
235
return this._entries.length;
241
* @method _getEntries
244
_getEntries: function() {
245
return this._entries;
250
* Adds entry to cache.
253
* @param e {Event.Facade} Event Facade with the following properties:
255
* <dt>entry (Object)</dt> <dd>The cached entry.</dd>
259
_defAddFn: function(e) {
260
var entries = this._entries,
262
max = this.get("max"),
265
// If uniqueKeys is true and item exists with this key, then remove it.
266
if (this.get("uniqueKeys")) {
267
pos = this._position(e.entry.request);
268
if (LANG.isValue(pos)) {
269
entries.splice(pos, 1);
273
// If the cache at or over capacity, make room by removing stalest
274
// element(s) starting at index-0.
275
while (max && entries.length >= max) {
279
// Add entry to cache in the newest position, at the end of the array
280
entries[entries.length] = entry;
286
* @method _defFlushFn
287
* @param e {Event.Facade} Event Facade object.
290
_defFlushFn: function(e) {
291
var entries = this._entries,
292
details = e.details[0],
295
//passed an item, flush only that
296
if(details && LANG.isValue(details.request)) {
297
pos = this._position(details.request);
299
if(LANG.isValue(pos)) {
300
entries.splice(pos,1);
304
//no item, flush everything
311
* Default overridable method compares current request with given cache entry.
312
* Returns true if current request matches the cached request, otherwise
313
* false. Implementers should override this method to customize the
314
* cache-matching algorithm.
317
* @param request {Object} Request object.
318
* @param entry {Object} Cached entry.
319
* @return {Boolean} True if current request matches given cached request, false otherwise.
322
_isMatch: function(request, entry) {
323
if(!entry.expires || new Date() < entry.expires) {
324
return (request === entry.request);
330
* Returns position of a request in the entries array, otherwise null.
333
* @param request {Object} Request object.
334
* @return {Number} Array position if found, null otherwise.
337
_position: function(request) {
338
// If cache is enabled...
339
var entries = this._entries,
340
length = entries.length,
343
if((this.get("max") === null) || this.get("max") > 0) {
344
// Loop through each cached entry starting from the newest
346
// Execute matching function
347
if(this._isMatch(request, entries[i])) {
356
/////////////////////////////////////////////////////////////////////////////
358
// Cache public methods
360
/////////////////////////////////////////////////////////////////////////////
363
* Adds a new entry to the cache of the format
364
* {request:request, response:response, cached:cached, expires:expires}.
365
* If cache is full, evicts the stalest entry before adding the new one.
368
* @param request {Object} Request value.
369
* @param response {Object} Response value.
371
add: function(request, response) {
372
var expires = this.get("expires");
373
if(this.get("initialized") && ((this.get("max") === null) || this.get("max") > 0) &&
374
(LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) {
375
this.fire("add", {entry: {
379
expires: isDate(expires) ? expires :
380
(expires ? new Date(new Date().getTime() + this.get("expires")) : null)
392
flush: function(request) {
393
this.fire("flush", { request: (LANG.isValue(request) ? request : null) });
397
* Retrieves cached object for given request, if available, and refreshes
398
* entry in the cache. Returns null if there is no cache match.
401
* @param request {Object} Request object.
402
* @return {Object} Cached object with the properties request and response, or null.
404
retrieve: function(request) {
405
// If cache is enabled...
406
var entries = this._entries,
407
length = entries.length,
411
if((length > 0) && ((this.get("max") === null) || (this.get("max") > 0))) {
412
this.fire("request", {request: request});
414
pos = this._position(request);
416
if(LANG.isValue(pos)) {
417
entry = entries[pos];
419
this.fire("retrieve", {entry: entry});
421
// Refresh the position of the cache hit
423
// Remove element from its original location
424
entries.splice(pos,1);
426
entries[entries.length] = entry;
439
}, '3.13.0', {"requires": ["base"]});