Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 497839f

Browse files
committed
feat($cacheFactory): add general purpose $cacheFactory service
1 parent 5487bdb commit 497839f

File tree

4 files changed

+471
-0
lines changed

4 files changed

+471
-0
lines changed

angularFiles.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ angularFiles = {
1010
'src/apis.js',
1111
'src/service/autoScroll.js',
1212
'src/service/browser.js',
13+
'src/service/cacheFactory.js',
1314
'src/service/compiler.js',
1415
'src/service/cookieStore.js',
1516
'src/service/cookies.js',

src/AngularPublic.js

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ function ngModule($provide, $injector) {
6868

6969
$provide.service('$autoScroll', $AutoScrollProvider);
7070
$provide.service('$browser', $BrowserProvider);
71+
$provide.service('$cacheFactory', $CacheFactoryProvider);
7172
$provide.service('$compile', $CompileProvider);
7273
$provide.service('$cookies', $CookiesProvider);
7374
$provide.service('$cookieStore', $CookieStoreProvider);

src/service/cacheFactory.js

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/**
2+
* @ngdoc object
3+
* @name angular.module.ng.$cacheFactory
4+
*
5+
* @description
6+
* Factory that constructs cache objects.
7+
*
8+
*
9+
* @param {string} cacheId Name or id of the newly created cache.
10+
* @param {object=} options Options object that specifies the cache behavior. Properties:
11+
*
12+
* - `{number=}` `capacity` — turns the cache into LRU cache.
13+
*
14+
* @returns {object} Newly created cache object with the following set of methods:
15+
*
16+
* - `{string}` `id()` — Returns id or name of the cache.
17+
* - `{number}` `size()` — Returns number of items currently in the cache
18+
* - `{void}` `put({string} key, {*} value)` — Puts a new key-value pair into the cache
19+
* - `{(*}} `get({string} key) — Returns cached value for `key` or undefined for cache miss.
20+
* - `{void}` `remove{string} key) — Removes a key-value pair from the cache.
21+
* - `{void}` `removeAll() — Removes all cached values.
22+
*
23+
*/
24+
function $CacheFactoryProvider() {
25+
26+
this.$get = function() {
27+
var caches = {};
28+
29+
function cacheFactory(cacheId, options) {
30+
if (cacheId in caches) {
31+
throw Error('cacheId ' + cacheId + ' taken');
32+
}
33+
34+
var size = 0,
35+
stats = extend({}, options, {id: cacheId}),
36+
data = {},
37+
capacity = (options && options.capacity) || Number.MAX_VALUE,
38+
lruHash = {},
39+
freshEnd = null,
40+
staleEnd = null;
41+
42+
return caches[cacheId] = {
43+
44+
put: function(key, value) {
45+
var lruEntry = lruHash[key] || (lruHash[key] = {key: key});
46+
47+
refresh(lruEntry);
48+
49+
if (isUndefined(value)) return;
50+
if (!(key in data)) size++;
51+
data[key] = value;
52+
53+
if (size > capacity) {
54+
this.remove(staleEnd.key);
55+
}
56+
},
57+
58+
59+
get: function(key) {
60+
var lruEntry = lruHash[key];
61+
62+
if (!lruEntry) return;
63+
64+
refresh(lruEntry);
65+
66+
return data[key];
67+
},
68+
69+
70+
remove: function(key) {
71+
var lruEntry = lruHash[key];
72+
73+
if (lruEntry == freshEnd) freshEnd = lruEntry.p;
74+
if (lruEntry == staleEnd) staleEnd = lruEntry.n;
75+
link(lruEntry.n,lruEntry.p);
76+
77+
delete lruHash[key];
78+
delete data[key];
79+
size--;
80+
},
81+
82+
83+
removeAll: function() {
84+
data = {};
85+
size = 0;
86+
lruHash = {};
87+
freshEnd = staleEnd = null;
88+
},
89+
90+
91+
destroy: function() {
92+
data = null;
93+
stats = null;
94+
lruHash = null;
95+
delete caches[cacheId];
96+
},
97+
98+
99+
info: function() {
100+
return extend({}, stats, {size: size});
101+
}
102+
};
103+
104+
105+
/**
106+
* makes the `entry` the freshEnd of the LRU linked list
107+
*/
108+
function refresh(entry) {
109+
if (entry != freshEnd) {
110+
if (!staleEnd) {
111+
staleEnd = entry;
112+
} else if (staleEnd == entry) {
113+
staleEnd = entry.n;
114+
}
115+
116+
link(entry.n, entry.p);
117+
link(entry, freshEnd);
118+
freshEnd = entry;
119+
freshEnd.n = null;
120+
}
121+
}
122+
123+
124+
/**
125+
* bidirectionally links two entries of the LRU linked list
126+
*/
127+
function link(nextEntry, prevEntry) {
128+
if (nextEntry != prevEntry) {
129+
if (nextEntry) nextEntry.p = prevEntry; //p stands for previous, 'prev' didn't minify
130+
if (prevEntry) prevEntry.n = nextEntry; //n stands for next, 'next' didn't minify
131+
}
132+
}
133+
}
134+
135+
136+
cacheFactory.info = function() {
137+
var info = {};
138+
forEach(caches, function(cache, cacheId) {
139+
info[cacheId] = cache.info();
140+
});
141+
return info;
142+
};
143+
144+
145+
cacheFactory.get = function(cacheId) {
146+
return caches[cacheId];
147+
};
148+
149+
150+
return cacheFactory;
151+
};
152+
}

0 commit comments

Comments
 (0)