Name: js-handler/node_modules/restify/node_modules/lru-cache/lib/lru-cache.js 
1:
;(function () { // closure for web browsers
2:
 
3:
if (typeof module === 'object' && module.exports) {
4:
  module.exports = LRUCache
5:
} else {
6:
  // just set the global for non-node platforms.
7:
  this.LRUCache = LRUCache
8:
}
9:
 
10:
function hOP (obj, key) {
11:
  return Object.prototype.hasOwnProperty.call(obj, key)
12:
}
13:
 
14:
function naiveLength () { return 1 }
15:
 
16:
function LRUCache (options) {
17:
  if (!(this instanceof LRUCache)) {
18:
    return new LRUCache(options)
19:
  }
20:
 
21:
  var max
22:
  if (typeof options === 'number') {
23:
    max = options
24:
    options = { max: max }
25:
  }
26:
 
27:
  if (!options) options = {}
28:
 
29:
  max = options.max
30:
 
31:
  var lengthCalculator = options.length || naiveLength
32:
 
33:
  if (typeof lengthCalculator !== "function") {
34:
    lengthCalculator = naiveLength
35:
  }
36:
 
37:
  if (!max || !(typeof max === "number") || max <= 0 ) {
38:
    // a little bit silly.  maybe this should throw?
39:
    max = Infinity
40:
  }
41:
 
42:
  var allowStale = options.stale || false
43:
 
44:
  var maxAge = options.maxAge || null
45:
 
46:
  var dispose = options.dispose
47:
 
48:
  var cache = Object.create(null) // hash of items by key
49:
    , lruList = Object.create(null) // list of items in order of use recency
50:
    , mru = 0 // most recently used
51:
    , lru = 0 // least recently used
52:
    , length = 0 // number of items in the list
53:
    , itemCount = 0
54:
 
55:
 
56:
  // resize the cache when the max changes.
57:
  Object.defineProperty(this, "max",
58:
    { set : function (mL) {
59:
        if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
60:
        max = mL
61:
        // if it gets above double max, trim right away.
62:
        // otherwise, do it whenever it's convenient.
63:
        if (length > max) trim()
64:
      }
65:
    , get : function () { return max }
66:
    , enumerable : true
67:
    })
68:
 
69:
  // resize the cache when the lengthCalculator changes.
70:
  Object.defineProperty(this, "lengthCalculator",
71:
    { set : function (lC) {
72:
        if (typeof lC !== "function") {
73:
          lengthCalculator = naiveLength
74:
          length = itemCount
75:
          for (var key in cache) {
76:
            cache[key].length = 1
77:
          }
78:
        } else {
79:
          lengthCalculator = lC
80:
          length = 0
81:
          for (var key in cache) {
82:
            cache[key].length = lengthCalculator(cache[key].value)
83:
            length += cache[key].length
84:
          }
85:
        }
86:
 
87:
        if (length > max) trim()
88:
      }
89:
    , get : function () { return lengthCalculator }
90:
    , enumerable : true
91:
    })
92:
 
93:
  Object.defineProperty(this, "length",
94:
    { get : function () { return length }
95:
    , enumerable : true
96:
    })
97:
 
98:
 
99:
  Object.defineProperty(this, "itemCount",
100:
    { get : function () { return itemCount }
101:
    , enumerable : true
102:
    })
103:
 
104:
  this.forEach = function (fn, thisp) {
105:
    thisp = thisp || this
106:
    var i = 0;
107:
    for (var k = mru - 1; k >= 0 && i < itemCount; k--) if (lruList[k]) {
108:
      i++
109:
      var hit = lruList[k]
110:
      fn.call(thisp, hit.value, hit.key, this)
111:
    }
112:
  }
113:
 
114:
  this.keys = function () {
115:
    var keys = new Array(itemCount)
116:
    var i = 0
117:
    for (var k = mru - 1; k >= 0 && i < itemCount; k--) if (lruList[k]) {
118:
      var hit = lruList[k]
119:
      keys[i++] = hit.key
120:
    }
121:
    return keys
122:
  }
123:
 
124:
  this.values = function () {
125:
    var values = new Array(itemCount)
126:
    var i = 0
127:
    for (var k = mru - 1; k >= 0 && i < itemCount; k--) if (lruList[k]) {
128:
      var hit = lruList[k]
129:
      values[i++] = hit.value
130:
    }
131:
    return values
132:
  }
133:
 
134:
  this.reset = function () {
135:
    if (dispose) {
136:
      for (var k in cache) {
137:
        dispose(k, cache[k].value)
138:
      }
139:
    }
140:
    cache = {}
141:
    lruList = {}
142:
    lru = 0
143:
    mru = 0
144:
    length = 0
145:
    itemCount = 0
146:
  }
147:
 
148:
  // Provided for debugging/dev purposes only. No promises whatsoever that
149:
  // this API stays stable.
150:
  this.dump = function () {
151:
    return cache
152:
  }
153:
 
154:
  this.dumpLru = function () {
155:
    return lruList
156:
  }
157:
 
158:
  this.set = function (key, value) {
159:
    if (hOP(cache, key)) {
160:
      // dispose of the old one before overwriting
161:
      if (dispose) dispose(key, cache[key].value)
162:
      if (maxAge) cache[key].now = Date.now()
163:
      cache[key].value = value
164:
      this.get(key)
165:
      return true
166:
    }
167:
 
168:
    var len = lengthCalculator(value)
169:
    var age = maxAge ? Date.now() : 0
170:
    var hit = new Entry(key, value, mru++, len, age)
171:
 
172:
    // oversized objects fall out of cache automatically.
173:
    if (hit.length > max) {
174:
      if (dispose) dispose(key, value)
175:
      return false
176:
    }
177:
 
178:
    length += hit.length
179:
    lruList[hit.lu] = cache[key] = hit
180:
    itemCount ++
181:
 
182:
    if (length > max) trim()
183:
    return true
184:
  }
185:
 
186:
  this.has = function (key) {
187:
    if (!hOP(cache, key)) return false
188:
    var hit = cache[key]
189:
    if (maxAge && (Date.now() - hit.now > maxAge)) {
190:
      return false
191:
    }
192:
    return true
193:
  }
194:
 
195:
  this.get = function (key) {
196:
    return get(key, true)
197:
  }
198:
 
199:
  this.peek = function (key) {
200:
    return get(key, false)
201:
  }
202:
 
203:
  function get (key, doUse) {
204:
    var hit = cache[key]
205:
    if (hit) {
206:
      if (maxAge && (Date.now() - hit.now > maxAge)) {
207:
        del(hit)
208:
        if (!allowStale) hit = undefined
209:
      } else {
210:
        if (doUse) use(hit)
211:
      }
212:
      if (hit) hit = hit.value
213:
    }
214:
    return hit
215:
  }
216:
 
217:
  function use (hit) {
218:
    shiftLU(hit)
219:
    hit.lu = mru ++
220:
    lruList[hit.lu] = hit
221:
  }
222:
 
223:
  this.del = function (key) {
224:
    del(cache[key])
225:
  }
226:
 
227:
  function trim () {
228:
    while (lru < mru && length > max)
229:
      del(lruList[lru])
230:
  }
231:
 
232:
  function shiftLU(hit) {
233:
    delete lruList[ hit.lu ]
234:
    while (lru < mru && !lruList[lru]) lru ++
235:
  }
236:
 
237:
  function del(hit) {
238:
    if (hit) {
239:
      if (dispose) dispose(hit.key, hit.value)
240:
      length -= hit.length
241:
      itemCount --
242:
      delete cache[ hit.key ]
243:
      shiftLU(hit)
244:
    }
245:
  }
246:
}
247:
 
248:
// classy, since V8 prefers predictable objects.
249:
function Entry (key, value, mru, len, age) {
250:
  this.key = key
251:
  this.value = value
252:
  this.lu = mru
253:
  this.length = len
254:
  this.now = age
255:
}
256:
 
257:
})()