Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: pkg/analyzer/lib/src/context/cache.dart

Issue 1342543007: Add ReentrantSynchronousStream and use it for cache invalidation events. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.context.cache; 5 library analyzer.src.context.cache;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 9
10 import 'package:analyzer/src/generated/engine.dart' 10 import 'package:analyzer/src/generated/engine.dart'
(...skipping 20 matching lines...) Expand all
31 static bool _TRACE_CHANGES = false; 31 static bool _TRACE_CHANGES = false;
32 32
33 /** 33 /**
34 * An array containing the partitions of which this cache is comprised. 34 * An array containing the partitions of which this cache is comprised.
35 */ 35 */
36 final List<CachePartition> _partitions; 36 final List<CachePartition> _partitions;
37 37
38 /** 38 /**
39 * The [StreamController] reporting [InvalidatedResult]s. 39 * The [StreamController] reporting [InvalidatedResult]s.
40 */ 40 */
41 final StreamController<InvalidatedResult> _onResultInvalidated = 41 final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
42 new StreamController<InvalidatedResult>.broadcast(sync: true); 42 new ReentrantSynchronousStream<InvalidatedResult>();
43 43
44 /** 44 /**
45 * Initialize a newly created cache to have the given [partitions]. The 45 * Initialize a newly created cache to have the given [partitions]. The
46 * partitions will be searched in the order in which they appear in the array, 46 * partitions will be searched in the order in which they appear in the array,
47 * so the most specific partition (usually an [SdkCachePartition]) should be 47 * so the most specific partition (usually an [SdkCachePartition]) should be
48 * first and the most general (usually a [UniversalCachePartition]) last. 48 * first and the most general (usually a [UniversalCachePartition]) last.
49 */ 49 */
50 AnalysisCache(this._partitions) { 50 AnalysisCache(this._partitions) {
51 for (CachePartition partition in _partitions) { 51 for (CachePartition partition in _partitions) {
52 partition.onResultInvalidated.listen((InvalidatedResult event) { 52 partition.onResultInvalidated.listen((InvalidatedResult event) {
53 _onResultInvalidated.add(event); 53 onResultInvalidated.add(event);
54 }); 54 });
55 } 55 }
56 } 56 }
57 57
58 /**
59 * Return the stream that is notified when a value is invalidated.
60 */
61 Stream<InvalidatedResult> get onResultInvalidated =>
62 _onResultInvalidated.stream;
63
64 // TODO(brianwilkerson) Implement or delete this. 58 // TODO(brianwilkerson) Implement or delete this.
65 // /** 59 // /**
66 // * Return information about each of the partitions in this cache. 60 // * Return information about each of the partitions in this cache.
67 // */ 61 // */
68 // List<AnalysisContextStatistics_PartitionData> get partitionData { 62 // List<AnalysisContextStatistics_PartitionData> get partitionData {
69 // int count = _partitions.length; 63 // int count = _partitions.length;
70 // List<AnalysisContextStatistics_PartitionData> data = 64 // List<AnalysisContextStatistics_PartitionData> data =
71 // new List<AnalysisContextStatistics_PartitionData>(count); 65 // new List<AnalysisContextStatistics_PartitionData>(count);
72 // for (int i = 0; i < count; i++) { 66 // for (int i = 0; i < count; i++) {
73 // CachePartition partition = _partitions[i]; 67 // CachePartition partition = _partitions[i];
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 if (entry != null) { 546 if (entry != null) {
553 entry._invalidate(dependentResult.result, delta); 547 entry._invalidate(dependentResult.result, delta);
554 } 548 }
555 } 549 }
556 // If empty, remove the entry altogether. 550 // If empty, remove the entry altogether.
557 if (_resultMap.isEmpty) { 551 if (_resultMap.isEmpty) {
558 _partition._targetMap.remove(target); 552 _partition._targetMap.remove(target);
559 _partition._removeIfSource(target); 553 _partition._removeIfSource(target);
560 } 554 }
561 // Notify controller. 555 // Notify controller.
562 _partition._onResultInvalidated 556 _partition.onResultInvalidated
563 .add(new InvalidatedResult(this, descriptor)); 557 .add(new InvalidatedResult(this, descriptor, thisData.value));
564 } 558 }
565 559
566 /** 560 /**
567 * Invalidates all the results of this entry, with propagation. 561 * Invalidates all the results of this entry, with propagation.
568 */ 562 */
569 void _invalidateAll() { 563 void _invalidateAll() {
570 List<ResultDescriptor> results = _resultMap.keys.toList(); 564 List<ResultDescriptor> results = _resultMap.keys.toList();
571 for (ResultDescriptor result in results) { 565 for (ResultDescriptor result in results) {
572 _invalidate(result, null); 566 _invalidate(result, null);
573 } 567 }
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 794
801 /** 795 /**
802 * A table mapping caching policies to the cache flush managers. 796 * A table mapping caching policies to the cache flush managers.
803 */ 797 */
804 final HashMap<ResultCachingPolicy, CacheFlushManager> _flushManagerMap = 798 final HashMap<ResultCachingPolicy, CacheFlushManager> _flushManagerMap =
805 new HashMap<ResultCachingPolicy, CacheFlushManager>(); 799 new HashMap<ResultCachingPolicy, CacheFlushManager>();
806 800
807 /** 801 /**
808 * The [StreamController] reporting [InvalidatedResult]s. 802 * The [StreamController] reporting [InvalidatedResult]s.
809 */ 803 */
810 final StreamController<InvalidatedResult> _onResultInvalidated = 804 final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
811 new StreamController<InvalidatedResult>.broadcast(sync: true); 805 new ReentrantSynchronousStream<InvalidatedResult>();
812 806
813 /** 807 /**
814 * A table mapping the targets belonging to this partition to the information 808 * A table mapping the targets belonging to this partition to the information
815 * known about those targets. 809 * known about those targets.
816 */ 810 */
817 HashMap<AnalysisTarget, CacheEntry> _targetMap = 811 HashMap<AnalysisTarget, CacheEntry> _targetMap =
818 new HashMap<AnalysisTarget, CacheEntry>(); 812 new HashMap<AnalysisTarget, CacheEntry>();
819 813
820 /** 814 /**
821 * A set of the [Source] targets. 815 * A set of the [Source] targets.
(...skipping 14 matching lines...) Expand all
836 /** 830 /**
837 * Return a table mapping the targets known to the context to the information 831 * Return a table mapping the targets known to the context to the information
838 * known about the target. 832 * known about the target.
839 * 833 *
840 * <b>Note:</b> This method is only visible for use by [AnalysisCache] and 834 * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
841 * should not be used for any other purpose. 835 * should not be used for any other purpose.
842 */ 836 */
843 Map<AnalysisTarget, CacheEntry> get map => _targetMap; 837 Map<AnalysisTarget, CacheEntry> get map => _targetMap;
844 838
845 /** 839 /**
846 * Return the stream that is notified when a value is invalidated.
847 */
848 Stream<InvalidatedResult> get onResultInvalidated =>
849 _onResultInvalidated.stream;
850
851 /**
852 * Notifies the partition that the client is going to stop using it. 840 * Notifies the partition that the client is going to stop using it.
853 */ 841 */
854 void dispose() { 842 void dispose() {
855 for (CacheEntry entry in _targetMap.values) { 843 for (CacheEntry entry in _targetMap.values) {
856 entry.dispose(); 844 entry.dispose();
857 } 845 }
858 _targetMap.clear(); 846 _targetMap.clear();
859 } 847 }
860 848
861 /** 849 /**
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 /** 1023 /**
1036 * The target in which the result was invalidated. 1024 * The target in which the result was invalidated.
1037 */ 1025 */
1038 final CacheEntry entry; 1026 final CacheEntry entry;
1039 1027
1040 /** 1028 /**
1041 * The descriptor of the result which was invalidated. 1029 * The descriptor of the result which was invalidated.
1042 */ 1030 */
1043 final ResultDescriptor descriptor; 1031 final ResultDescriptor descriptor;
1044 1032
1045 InvalidatedResult(this.entry, this.descriptor); 1033 /**
1034 * The value of the result which was invalidated.
1035 */
1036 final Object value;
1037
1038 InvalidatedResult(this.entry, this.descriptor, this.value);
1046 1039
1047 @override 1040 @override
1048 String toString() => '$descriptor of ${entry.target}'; 1041 String toString() => '$descriptor of ${entry.target}';
1049 } 1042 }
1050 1043
1051 /** 1044 /**
1045 * A Stream-like interface, which broadcasts events synchronously.
1046 * If a second event is fired while delivering a first event, then the second
1047 * event will be delivered first, and then delivering of the first will be
1048 * continued.
1049 */
1050 class ReentrantSynchronousStream<T> {
1051 final List<Function> listeners = <Function>[];
1052
1053 /**
1054 * Send the given [event] to the stream.
1055 */
1056 void add(T event) {
1057 List<Function> listeners = this.listeners.toList();
1058 for (Function listener in listeners) {
1059 listener(event);
1060 }
1061 }
1062
1063 /**
1064 * Listen for the events in this stream.
1065 * Note that if the [listener] fires a new event, then the [listener] will be
1066 * invoked again before returning from the [add] invocation.
1067 */
1068 void listen(void listener(T event)) {
1069 listeners.add(listener);
1070 }
1071 }
1072
1073 /**
1052 * The data about a single analysis result that is stored in a [CacheEntry]. 1074 * The data about a single analysis result that is stored in a [CacheEntry].
1053 */ 1075 */
1054 // TODO(brianwilkerson) Consider making this a generic class so that the value 1076 // TODO(brianwilkerson) Consider making this a generic class so that the value
1055 // can be typed. 1077 // can be typed.
1056 class ResultData { 1078 class ResultData {
1057 /** 1079 /**
1058 * The [ResultDescriptor] this result is for. 1080 * The [ResultDescriptor] this result is for.
1059 */ 1081 */
1060 final ResultDescriptor descriptor; 1082 final ResultDescriptor descriptor;
1061 1083
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 void resultAccessed(TargetedResult result) {} 1166 void resultAccessed(TargetedResult result) {}
1145 1167
1146 @override 1168 @override
1147 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { 1169 List<TargetedResult> resultStored(TargetedResult newResult, newValue) {
1148 return TargetedResult.EMPTY_LIST; 1170 return TargetedResult.EMPTY_LIST;
1149 } 1171 }
1150 1172
1151 @override 1173 @override
1152 void targetRemoved(AnalysisTarget target) {} 1174 void targetRemoved(AnalysisTarget target) {}
1153 } 1175 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698