Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 20fd616

Browse files
committed
feat(cache): Move cache out of core, add a CacheRegister
1 parent 8c271f7 commit 20fd616

13 files changed

+208
-5
lines changed

lib/application.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ import 'package:intl/date_symbol_data_local.dart';
7373
import 'package:di/di.dart';
7474
import 'package:angular/angular.dart';
7575
import 'package:angular/perf/module.dart';
76+
import 'package:angular/cache/module.dart';
7677
import 'package:angular/core/module_internal.dart';
7778
import 'package:angular/core/registry.dart';
7879
import 'package:angular/core_dom/module_internal.dart';
@@ -94,6 +95,7 @@ import 'package:angular/core_dom/static_keys.dart';
9495
*/
9596
class AngularModule extends Module {
9697
AngularModule() {
98+
install(new CacheModule());
9799
install(new CoreModule());
98100
install(new CoreDomModule());
99101
install(new DirectiveModule());

lib/core/cache.dart renamed to lib/cache/cache.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
part of angular.core_internal;
1+
part of angular.cache;
22

33
class CacheStats {
44
final int capacity;
@@ -32,10 +32,15 @@ abstract class Cache<K, V> {
3232
/**
3333
* Removes all entries from the cache.
3434
*/
35+
@Deprecated('Use clear() instead')
3536
void removeAll();
3637
int get capacity;
38+
@Deprecated('Use length instead')
3739
int get size;
3840
CacheStats stats();
41+
42+
void clear() => removeAll();
43+
int get length => size;
3944
}
4045

4146

lib/cache/cache_register.dart

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
part of angular.cache;
2+
3+
class CacheRegisterStats {
4+
final String name;
5+
int length;
6+
7+
CacheRegisterStats(this.name);
8+
}
9+
10+
@Injectable()
11+
class CacheRegister {
12+
Map<String, Map> _caches = {};
13+
List<CacheRegisterStats> _stats = null;
14+
15+
/**
16+
* Registers a cache with the CacheRegister. The [name] is used for in the stats as
17+
* well as a key for [clear].
18+
*/
19+
void registerCache(String name, Map cache) {
20+
if (_caches.containsKey(name)) {
21+
throw "Cache [$name] already registered";
22+
}
23+
_caches[name] = cache;
24+
25+
// The stats object needs to be updated.
26+
_stats = null;
27+
28+
}
29+
30+
/**
31+
* A list of caches and their sizes.
32+
*/
33+
List<CacheRegisterStats> get stats {
34+
if (_stats == null) {
35+
_stats = [];
36+
_caches.forEach((k, v) {
37+
_stats.add(new CacheRegisterStats(k));
38+
});
39+
}
40+
41+
_stats.forEach((CacheRegisterStats stat) {
42+
stat.length = _caches[stat.name].length;
43+
});
44+
return _stats;
45+
}
46+
47+
/**
48+
* Clears one or all the caches. If [name] is omitted, all caches will be cleared.
49+
* Otherwise, only the cache named [name] will be cleared.
50+
*/
51+
void clear([String name]) {
52+
if (name == null) {
53+
_caches.forEach((k, Map v) {
54+
v.clear();
55+
});
56+
return;
57+
}
58+
var cache = _caches[name];
59+
if (cache == null) {
60+
return;
61+
}
62+
_caches[name].clear();
63+
}
64+
}

lib/cache/future_cache.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
part of angular.cache;
2+
3+
class FutureCache<K, V> extends LruCache<K, Future<V>> {
4+
FutureCache({int capacity}) : super(capacity: capacity);
5+
6+
Future<V> put(K key, Future<V> value) {
7+
super.put(key, value);
8+
value.then((result) {
9+
// Replace the old value with a cheaper version.
10+
super.put(key, new Future.value(result));
11+
});
12+
}
13+
}

lib/cache/module.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library angular.cache;
2+
3+
import 'dart:collection';
4+
import 'dart:async';
5+
6+
import 'package:di/di.dart';
7+
import 'package:angular/core/annotation_src.dart';
8+
9+
part "cache.dart";
10+
part "cache_register.dart";
11+
part "future_cache.dart";
12+
13+
class CacheModule extends Module {
14+
CacheModule() {
15+
bind(CacheRegister);
16+
}
17+
}

lib/core/module.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ export "package:angular/change_detection/change_detection.dart" show
2222
AvgStopwatch,
2323
FieldGetterFactory;
2424

25+
export "package:angular/cache/module.dart" show
26+
Cache,
27+
CacheRegister,
28+
CacheRegisterStats;
29+
2530
export "package:angular/core_dom/module_internal.dart" show
2631
Animation,
2732
AnimationResult,
2833
BrowserCookies,
29-
Cache,
3034
Compiler,
3135
CompilerConfig,
3236
Cookies,

lib/core/module_internal.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import 'package:angular/core/parser/utils.dart';
2424
import 'package:angular/core/registry.dart';
2525
import 'package:angular/core/static_keys.dart';
2626

27-
part "cache.dart";
2827
part "exception_handler.dart";
2928
part "interpolate.dart";
3029
part "scope.dart";
@@ -36,7 +35,6 @@ class CoreModule extends Module {
3635
bind(ScopeDigestTTL);
3736

3837
bind(MetadataExtractor);
39-
bind(Cache);
4038
bind(ExceptionHandler);
4139
bind(FormatterMap);
4240
bind(Interpolate);

lib/core_dom/module_internal.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import 'dart:js' as js;
88
import 'package:di/di.dart';
99
import 'package:perf_api/perf_api.dart';
1010

11+
import 'package:angular/cache/module.dart';
12+
1113
import 'package:angular/core/annotation.dart';
1214
import 'package:angular/core/annotation_src.dart' show SHADOW_DOM_INJECTOR_NAME;
1315
import 'package:angular/core/module_internal.dart';

test/_specs.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export 'package:di/dynamic_injector.dart';
1818
export 'package:angular/angular.dart';
1919
export 'package:angular/application.dart';
2020
export 'package:angular/introspection.dart';
21+
export 'package:angular/cache/module.dart';
2122
export 'package:angular/core/annotation.dart';
2223
export 'package:angular/core/registry.dart';
2324
export 'package:angular/core/module_internal.dart';

test/angular_spec.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ main() {
9494
var ALLOWED_NAMES = [
9595
"angular.app.AngularModule",
9696
"angular.app.Application",
97+
"angular.cache.Cache",
98+
"angular.cache.CacheRegister",
99+
"angular.cache.CacheRegisterStats",
97100
"angular.core.annotation.ShadowRootAware",
98101
"angular.core.annotation_src.AttachAware",
99102
"angular.core.annotation_src.Component",
@@ -142,7 +145,6 @@ main() {
142145
"angular.core.dom_internal.ViewCache",
143146
"angular.core.dom_internal.ViewFactory",
144147
"angular.core.dom_internal.ViewPort",
145-
"angular.core_internal.CacheStats",
146148
"angular.core_internal.ExceptionHandler",
147149
"angular.core_internal.Interpolate",
148150
"angular.core_internal.RootScope",

test/cache/cache_register_spec.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library cache_register_spec;
2+
3+
import '../_specs.dart';
4+
5+
main() => describe('CacheRegister', () {
6+
it('should clear caches', (CacheRegister register) {
7+
var map = {'a': 2};
8+
var map2 = {'b': 3};
9+
expect(map.length).toEqual(1);
10+
expect(map2.length).toEqual(1);
11+
12+
register.registerCache('a', map);
13+
register.registerCache('b', map2);
14+
register.clear('a');
15+
expect(map.length).toEqual(0);
16+
expect(map2.length).toEqual(1);
17+
18+
map['a'] = 2;
19+
register.clear();
20+
expect(map.length).toEqual(0);
21+
expect(map2.length).toEqual(0);
22+
23+
24+
});
25+
26+
it('should return stats when empty', (CacheRegister register) {
27+
expect(register.stats).toEqual([]);
28+
});
29+
30+
it('should return correct stats', (CacheRegister register) {
31+
var map = {'a': 2};
32+
var map2 = {'b': 3, 'c': 4};
33+
register.registerCache('a', map);
34+
register.registerCache('b', map2);
35+
36+
expect(register.stats.length).toEqual(2);
37+
if (register.stats[0].name == 'a') {
38+
expect(register.stats[0].length).toEqual(1);
39+
expect(register.stats[1].name).toEqual('b');
40+
expect(register.stats[1].length).toEqual(2);
41+
} else {
42+
expect(register.stats[0].name).toEqual('b');
43+
expect(register.stats[0].length).toEqual(2);
44+
expect(register.stats[1].name).toEqual('a');
45+
expect(register.stats[1].length).toEqual(1);
46+
}
47+
48+
});
49+
});
File renamed without changes.

test/cache/future_cache_spec.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
library future_cache_spec;
2+
3+
import 'dart:async';
4+
import '../_specs.dart';
5+
6+
main() => describe('FutureCache', () {
7+
var cache;
8+
beforeEach(() {
9+
cache = new FutureCache();
10+
});
11+
12+
it('should return the future immediately', async(() {
13+
var completer = new Completer();
14+
cache.put('a', completer.future);
15+
var fromCache = cache.get('a');
16+
17+
var result;
18+
fromCache.then((value) { result = value; });
19+
expect(result).toBeNull();
20+
// We should get the same future back.
21+
expect(fromCache).toBe(completer.future);
22+
23+
completer.complete(6);
24+
microLeap();
25+
26+
expect(result).toEqual(6);
27+
}));
28+
29+
it('should return a different future after being resolved', async(() {
30+
var completer = new Completer();
31+
cache.put('a', completer.future);
32+
completer.complete(6);
33+
microLeap();
34+
35+
var fromCache = cache.get('a');
36+
37+
var result;
38+
fromCache.then((value) { result = value; });
39+
expect(result).toBeNull();
40+
// Different future.
41+
expect(fromCache).not.toBe(completer.future);
42+
43+
microLeap();
44+
expect(result).toEqual(6);
45+
}));
46+
});

0 commit comments

Comments
 (0)