1 |
|
2 |
|
3 |
|
4 |
|
5 | var crypto = require('crypto')
|
6 | , nodes = require('../nodes');
|
7 |
|
8 | var MemoryCache = module.exports = function(options) {
|
9 | options = options || {};
|
10 | this.limit = options['cache limit'] || 256;
|
11 | this._cache = {};
|
12 | this.length = 0;
|
13 | this.head = this.tail = null;
|
14 | };
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | MemoryCache.prototype.set = function(key, value) {
|
25 | var clone = value.clone()
|
26 | , item;
|
27 |
|
28 | clone.filename = nodes.filename;
|
29 | clone.lineno = nodes.lineno;
|
30 | clone.column = nodes.column;
|
31 | item = { key: key, value: clone };
|
32 | this._cache[key] = item;
|
33 |
|
34 | if (this.tail) {
|
35 | this.tail.next = item;
|
36 | item.prev = this.tail;
|
37 | } else {
|
38 | this.head = item;
|
39 | }
|
40 |
|
41 | this.tail = item;
|
42 | if (this.length++ == this.limit) this.purge();
|
43 | };
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | MemoryCache.prototype.get = function(key) {
|
54 | var item = this._cache[key]
|
55 | , val = item.value.clone();
|
56 |
|
57 | if (item == this.tail) return val;
|
58 | if (item.next) {
|
59 | if (item == this.head) this.head = item.next;
|
60 | item.next.prev = item.prev;
|
61 | }
|
62 | if (item.prev) item.prev.next = item.next;
|
63 |
|
64 | item.next = null;
|
65 | item.prev = this.tail;
|
66 |
|
67 | if (this.tail) this.tail.next = item;
|
68 | this.tail = item;
|
69 |
|
70 | return val;
|
71 | };
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 | MemoryCache.prototype.has = function(key) {
|
82 | return !!this._cache[key];
|
83 | };
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 | MemoryCache.prototype.key = function(str, options) {
|
95 | var hash = crypto.createHash('sha1');
|
96 | hash.update(str + options.prefix);
|
97 | return hash.digest('hex');
|
98 | };
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 | MemoryCache.prototype.purge = function() {
|
107 | var item = this.head;
|
108 |
|
109 | if (this.head.next) {
|
110 | this.head = this.head.next;
|
111 | this.head.prev = null;
|
112 | }
|
113 |
|
114 | this._cache[item.key] = item.prev = item.next = null;
|
115 | this.length--;
|
116 | };
|