[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('cache-base', function (Y, NAME) { 9 10 /** 11 * The Cache utility provides a common configurable interface for components to 12 * cache and retrieve data from a local JavaScript struct. 13 * 14 * @module cache 15 * @main 16 */ 17 18 /** 19 * Provides the base class for the YUI Cache utility. 20 * 21 * @submodule cache-base 22 */ 23 var LANG = Y.Lang, 24 isDate = Y.Lang.isDate, 25 26 /** 27 * Base class for the YUI Cache utility. 28 * @class Cache 29 * @extends Base 30 * @constructor 31 */ 32 Cache = function() { 33 Cache.superclass.constructor.apply(this, arguments); 34 }; 35 36 ///////////////////////////////////////////////////////////////////////////// 37 // 38 // Cache static properties 39 // 40 ///////////////////////////////////////////////////////////////////////////// 41 Y.mix(Cache, { 42 /** 43 * Class name. 44 * 45 * @property NAME 46 * @type String 47 * @static 48 * @final 49 * @value "cache" 50 */ 51 NAME: "cache", 52 53 54 ATTRS: { 55 ///////////////////////////////////////////////////////////////////////////// 56 // 57 // Cache Attributes 58 // 59 ///////////////////////////////////////////////////////////////////////////// 60 61 /** 62 * @attribute max 63 * @description Maximum number of entries the Cache can hold. 64 * Set to 0 to turn off caching. 65 * @type Number 66 * @default 0 67 */ 68 max: { 69 value: 0, 70 setter: "_setMax" 71 }, 72 73 /** 74 * @attribute size 75 * @description Number of entries currently cached. 76 * @type Number 77 */ 78 size: { 79 readOnly: true, 80 getter: "_getSize" 81 }, 82 83 /** 84 * @attribute uniqueKeys 85 * @description Validate uniqueness of stored keys. Default is false and 86 * is more performant. 87 * @type Boolean 88 */ 89 uniqueKeys: { 90 value: false 91 }, 92 93 /** 94 * @attribute expires 95 * @description Absolute Date when data expires or 96 * relative number of milliseconds. Zero disables expiration. 97 * @type Date | Number 98 * @default 0 99 */ 100 expires: { 101 value: 0, 102 validator: function(v) { 103 return Y.Lang.isDate(v) || (Y.Lang.isNumber(v) && v >= 0); 104 } 105 }, 106 107 /** 108 * @attribute entries 109 * @description Cached entries. 110 * @type Array 111 */ 112 entries: { 113 readOnly: true, 114 getter: "_getEntries" 115 } 116 } 117 }); 118 119 Y.extend(Cache, Y.Base, { 120 ///////////////////////////////////////////////////////////////////////////// 121 // 122 // Cache private properties 123 // 124 ///////////////////////////////////////////////////////////////////////////// 125 126 /** 127 * Array of request/response objects indexed chronologically. 128 * 129 * @property _entries 130 * @type Object[] 131 * @private 132 */ 133 _entries: null, 134 135 ///////////////////////////////////////////////////////////////////////////// 136 // 137 // Cache private methods 138 // 139 ///////////////////////////////////////////////////////////////////////////// 140 141 /** 142 * @method initializer 143 * @description Internal init() handler. 144 * @param config {Object} Config object. 145 * @private 146 */ 147 initializer: function(config) { 148 149 /** 150 * @event add 151 * @description Fired when an entry is added. 152 * @param e {EventFacade} Event Facade with the following properties: 153 * <dl> 154 * <dt>entry (Object)</dt> <dd>The cached entry.</dd> 155 * </dl> 156 * @preventable _defAddFn 157 */ 158 this.publish("add", {defaultFn: this._defAddFn}); 159 160 /** 161 * @event flush 162 * @description Fired when the cache is flushed. 163 * @param e {EventFacade} Event Facade object. 164 * @preventable _defFlushFn 165 */ 166 this.publish("flush", {defaultFn: this._defFlushFn}); 167 168 /** 169 * @event request 170 * @description Fired when an entry is requested from the cache. 171 * @param e {EventFacade} Event Facade with the following properties: 172 * <dl> 173 * <dt>request (Object)</dt> <dd>The request object.</dd> 174 * </dl> 175 */ 176 177 /** 178 * @event retrieve 179 * @description Fired when an entry is retrieved from the cache. 180 * @param e {EventFacade} Event Facade with the following properties: 181 * <dl> 182 * <dt>entry (Object)</dt> <dd>The retrieved entry.</dd> 183 * </dl> 184 */ 185 186 // Initialize internal values 187 this._entries = []; 188 Y.log("Cache initialized", "info", "cache"); 189 }, 190 191 /** 192 * @method destructor 193 * @description Internal destroy() handler. 194 * @private 195 */ 196 destructor: function() { 197 this._entries = []; 198 Y.log("Cache destroyed", "info", "cache"); 199 }, 200 201 ///////////////////////////////////////////////////////////////////////////// 202 // 203 // Cache protected methods 204 // 205 ///////////////////////////////////////////////////////////////////////////// 206 207 /** 208 * Sets max. 209 * 210 * @method _setMax 211 * @protected 212 */ 213 _setMax: function(value) { 214 // If the cache is full, make room by removing stalest element (index=0) 215 var entries = this._entries; 216 if(value > 0) { 217 if(entries) { 218 while(entries.length > value) { 219 entries.shift(); 220 } 221 } 222 } 223 else { 224 value = 0; 225 this._entries = []; 226 } 227 return value; 228 }, 229 230 /** 231 * Gets size. 232 * 233 * @method _getSize 234 * @protected 235 */ 236 _getSize: function() { 237 return this._entries.length; 238 }, 239 240 /** 241 * Gets all entries. 242 * 243 * @method _getEntries 244 * @protected 245 */ 246 _getEntries: function() { 247 return this._entries; 248 }, 249 250 251 /** 252 * Adds entry to cache. 253 * 254 * @method _defAddFn 255 * @param e {EventFacade} Event Facade with the following properties: 256 * <dl> 257 * <dt>entry (Object)</dt> <dd>The cached entry.</dd> 258 * </dl> 259 * @protected 260 */ 261 _defAddFn: function(e) { 262 var entries = this._entries, 263 entry = e.entry, 264 max = this.get("max"), 265 pos; 266 267 // If uniqueKeys is true and item exists with this key, then remove it. 268 if (this.get("uniqueKeys")) { 269 pos = this._position(e.entry.request); 270 if (LANG.isValue(pos)) { 271 entries.splice(pos, 1); 272 } 273 } 274 275 // If the cache at or over capacity, make room by removing stalest 276 // element(s) starting at index-0. 277 while (max && entries.length >= max) { 278 entries.shift(); 279 } 280 281 // Add entry to cache in the newest position, at the end of the array 282 entries[entries.length] = entry; 283 Y.log("Cached entry: " + Y.dump(entry), "info", "cache"); 284 }, 285 286 /** 287 * Flushes cache. 288 * 289 * @method _defFlushFn 290 * @param e {EventFacade} Event Facade object. 291 * @protected 292 */ 293 _defFlushFn: function(e) { 294 var entries = this._entries, 295 details = e.details[0], 296 pos; 297 298 //passed an item, flush only that 299 if(details && LANG.isValue(details.request)) { 300 pos = this._position(details.request); 301 302 if(LANG.isValue(pos)) { 303 entries.splice(pos,1); 304 305 Y.log("Flushed cache item " + Y.dump(details.request), "info", "cache"); 306 } 307 } 308 //no item, flush everything 309 else { 310 this._entries = []; 311 Y.log("Cache flushed", "info", "cache"); 312 } 313 }, 314 315 /** 316 * Default overridable method compares current request with given cache entry. 317 * Returns true if current request matches the cached request, otherwise 318 * false. Implementers should override this method to customize the 319 * cache-matching algorithm. 320 * 321 * @method _isMatch 322 * @param request {Object} Request object. 323 * @param entry {Object} Cached entry. 324 * @return {Boolean} True if current request matches given cached request, false otherwise. 325 * @protected 326 */ 327 _isMatch: function(request, entry) { 328 if(!entry.expires || new Date() < entry.expires) { 329 return (request === entry.request); 330 } 331 return false; 332 }, 333 334 /** 335 * Returns position of a request in the entries array, otherwise null. 336 * 337 * @method _position 338 * @param request {Object} Request object. 339 * @return {Number} Array position if found, null otherwise. 340 * @protected 341 */ 342 _position: function(request) { 343 // If cache is enabled... 344 var entries = this._entries, 345 length = entries.length, 346 i = length-1; 347 348 if((this.get("max") === null) || this.get("max") > 0) { 349 // Loop through each cached entry starting from the newest 350 for(; i >= 0; i--) { 351 // Execute matching function 352 if(this._isMatch(request, entries[i])) { 353 return i; 354 } 355 } 356 } 357 358 return null; 359 }, 360 361 ///////////////////////////////////////////////////////////////////////////// 362 // 363 // Cache public methods 364 // 365 ///////////////////////////////////////////////////////////////////////////// 366 367 /** 368 * Adds a new entry to the cache of the format 369 * {request:request, response:response, cached:cached, expires:expires}. 370 * If cache is full, evicts the stalest entry before adding the new one. 371 * 372 * @method add 373 * @param request {Object} Request value. 374 * @param response {Object} Response value. 375 */ 376 add: function(request, response) { 377 var expires = this.get("expires"); 378 if(this.get("initialized") && ((this.get("max") === null) || this.get("max") > 0) && 379 (LANG.isValue(request) || LANG.isNull(request) || LANG.isUndefined(request))) { 380 this.fire("add", {entry: { 381 request:request, 382 response:response, 383 cached: new Date(), 384 expires: isDate(expires) ? expires : 385 (expires ? new Date(new Date().getTime() + this.get("expires")) : null) 386 }}); 387 } 388 else { 389 Y.log("Could not add " + Y.dump(response) + " to cache for " + Y.dump(request), "info", "cache"); 390 } 391 }, 392 393 /** 394 * Flushes cache. 395 * 396 * @method flush 397 */ 398 flush: function(request) { 399 this.fire("flush", { request: (LANG.isValue(request) ? request : null) }); 400 }, 401 402 /** 403 * Retrieves cached object for given request, if available, and refreshes 404 * entry in the cache. Returns null if there is no cache match. 405 * 406 * @method retrieve 407 * @param request {Object} Request object. 408 * @return {Object} Cached object with the properties request and response, or null. 409 */ 410 retrieve: function(request) { 411 // If cache is enabled... 412 var entries = this._entries, 413 length = entries.length, 414 entry = null, 415 pos; 416 417 if((length > 0) && ((this.get("max") === null) || (this.get("max") > 0))) { 418 this.fire("request", {request: request}); 419 420 pos = this._position(request); 421 422 if(LANG.isValue(pos)) { 423 entry = entries[pos]; 424 425 this.fire("retrieve", {entry: entry}); 426 427 // Refresh the position of the cache hit 428 if(pos < length-1) { 429 // Remove element from its original location 430 entries.splice(pos,1); 431 // Add as newest 432 entries[entries.length] = entry; 433 Y.log("Refreshed cache entry: " + Y.dump(entry) + 434 " for request: " + Y.dump(request), "info", "cache"); 435 } 436 437 Y.log("Retrieved cached response: " + Y.dump(entry) + 438 " for request: " + Y.dump(request), "info", "cache"); 439 return entry; 440 } 441 } 442 return null; 443 } 444 }); 445 446 Y.Cache = Cache; 447 448 449 }, '3.17.2', {"requires": ["base"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |