wzp
2021-05-13 7d694a9113118daec5be7ac224dab46a3b20f106
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
'use strict'
var DEFAULT_MAXAGE = 60000
 
var expiration = {}
var history = {}
var expireListeners = {}
 
var size = 0
var interval = null
 
function get (pid, maxage) {
  if (maxage <= 0) {
    return
  }
 
  if (history[pid] !== undefined) {
    expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
  }
 
  return history[pid]
}
 
function set (pid, object, maxage, onExpire) {
  if (object === undefined || maxage <= 0) return
 
  expiration[pid] = Date.now() + (maxage || DEFAULT_MAXAGE)
  if (history[pid] === undefined) {
    size++
    sheduleInvalidator(maxage)
  }
 
  history[pid] = object
  if (onExpire) {
    expireListeners[pid] = onExpire
  }
}
 
function sheduleInvalidator (maxage) {
  if (size > 0) {
    if (interval === null) {
      interval = setInterval(runInvalidator, (maxage || DEFAULT_MAXAGE) / 2)
      if (typeof interval.unref === "function") { 
        interval.unref()
      }
    }
 
    return
  }
 
  if (interval !== null) {
    clearInterval(interval)
    interval = null
  }
}
 
function runInvalidator () {
  var now = Date.now()
  var pids = Object.keys(expiration)
  for (var i = 0; i < pids.length; i++) {
    var pid = pids[i]
    if (expiration[pid] < now) {
      size--
      if (expireListeners[pid]) {
        expireListeners[pid](history[pid])
      }
 
      delete history[pid]
      delete expiration[pid]
      delete expireListeners[pid]
    }
  }
  sheduleInvalidator()
}
 
function deleteLoop (obj) { for (const i in obj) { delete obj[i] } }
 
function clear () {
  if (interval !== null) {
    clearInterval(interval)
    interval = null
  }
 
  deleteLoop(history)
  deleteLoop(expiration)
  deleteLoop(expireListeners)
}
 
module.exports = {
  get: get,
  set: set,
  clear: clear
}