| 3389 | var caches = {}; |
| 3390 | |
| 3391 | function cacheFactory(cacheId, options) { |
| 3392 | if (cacheId in caches) { |
| 3393 | throw Error('cacheId ' + cacheId + ' taken'); |
| 3394 | } |
| 3395 | |
| 3396 | var size = 0, |
| 3397 | stats = extend({}, options, {id: cacheId}), |
| 3398 | data = {}, |
| 3399 | capacity = (options && options.capacity) || Number.MAX_VALUE, |
| 3400 | lruHash = {}, |
| 3401 | freshEnd = null, |
| 3402 | staleEnd = null; |
| 3403 | |
| 3404 | return caches[cacheId] = { |
| 3405 | |
| 3406 | put: function(key, value) { |
| 3407 | var lruEntry = lruHash[key] || (lruHash[key] = {key: key}); |
| 3408 | |
| 3409 | refresh(lruEntry); |
| 3410 | |
| 3411 | if (isUndefined(value)) return; |
| 3412 | if (!(key in data)) size++; |
| 3413 | data[key] = value; |
| 3414 | |
| 3415 | if (size > capacity) { |
| 3416 | this.remove(staleEnd.key); |
| 3417 | } |
| 3418 | }, |
| 3419 | |
| 3420 | |
| 3421 | get: function(key) { |
| 3422 | var lruEntry = lruHash[key]; |
| 3423 | |
| 3424 | if (!lruEntry) return; |
| 3425 | |
| 3426 | refresh(lruEntry); |
| 3427 | |
| 3428 | return data[key]; |
| 3429 | }, |
| 3430 | |
| 3431 | |
| 3432 | remove: function(key) { |
| 3433 | var lruEntry = lruHash[key]; |
| 3434 | |
| 3435 | if (!lruEntry) return; |
| 3436 | |
| 3437 | if (lruEntry == freshEnd) freshEnd = lruEntry.p; |
| 3438 | if (lruEntry == staleEnd) staleEnd = lruEntry.n; |
| 3439 | link(lruEntry.n,lruEntry.p); |
| 3440 | |
| 3441 | delete lruHash[key]; |
| 3442 | delete data[key]; |
| 3443 | size--; |
| 3444 | }, |
| 3445 | |
| 3446 | |
| 3447 | removeAll: function() { |
| 3448 | data = {}; |