OLD | NEW |
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:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/src/generated/engine.dart' | 9 import 'package:analyzer/src/generated/engine.dart' |
10 show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority; | 10 show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 MapIterator<AnalysisTarget, CacheEntry> iterator() { | 108 MapIterator<AnalysisTarget, CacheEntry> iterator() { |
109 int count = _partitions.length; | 109 int count = _partitions.length; |
110 List<Map<AnalysisTarget, CacheEntry>> maps = new List<Map>(count); | 110 List<Map<AnalysisTarget, CacheEntry>> maps = new List<Map>(count); |
111 for (int i = 0; i < count; i++) { | 111 for (int i = 0; i < count; i++) { |
112 maps[i] = _partitions[i].map; | 112 maps[i] = _partitions[i].map; |
113 } | 113 } |
114 return new MultipleMapIterator<AnalysisTarget, CacheEntry>(maps); | 114 return new MultipleMapIterator<AnalysisTarget, CacheEntry>(maps); |
115 } | 115 } |
116 | 116 |
117 /** | 117 /** |
118 * Associate the given [entry] with the given [target]. | 118 * Puts the given [entry] into the cache. |
119 */ | 119 */ |
120 void put(AnalysisTarget target, CacheEntry entry) { | 120 void put(CacheEntry entry) { |
| 121 AnalysisTarget target = entry.target; |
121 entry.fixExceptionState(); | 122 entry.fixExceptionState(); |
122 int count = _partitions.length; | 123 int count = _partitions.length; |
123 for (int i = 0; i < count; i++) { | 124 for (int i = 0; i < count; i++) { |
124 CachePartition partition = _partitions[i]; | 125 CachePartition partition = _partitions[i]; |
125 if (partition.isResponsibleFor(target)) { | 126 if (partition.isResponsibleFor(target)) { |
126 if (_TRACE_CHANGES) { | 127 if (_TRACE_CHANGES) { |
127 CacheEntry oldEntry = partition.get(target); | 128 CacheEntry oldEntry = partition.get(target); |
128 if (oldEntry == null) { | 129 if (oldEntry == null) { |
129 AnalysisEngine.instance.logger | 130 AnalysisEngine.instance.logger |
130 .logInformation('Added a cache entry for $target.'); | 131 .logInformation('Added a cache entry for $target.'); |
131 } else { | 132 } else { |
132 AnalysisEngine.instance.logger | 133 AnalysisEngine.instance.logger |
133 .logInformation('Modified the cache entry for $target.'); | 134 .logInformation('Modified the cache entry for $target.'); |
134 // 'Diff = ${entry.getDiff(oldEntry)}'); | 135 // 'Diff = ${entry.getDiff(oldEntry)}'); |
135 } | 136 } |
136 } | 137 } |
137 partition.put(target, entry); | 138 partition.put(entry); |
138 return; | 139 return; |
139 } | 140 } |
140 } | 141 } |
141 // TODO(brianwilkerson) Handle the case where no partition was found, | 142 // TODO(brianwilkerson) Handle the case where no partition was found, |
142 // possibly by throwing an exception. | 143 // possibly by throwing an exception. |
143 } | 144 } |
144 | 145 |
145 /** | 146 /** |
146 * Remove all information related to the given [target] from this cache. | 147 * Remove all information related to the given [target] from this cache. |
147 */ | 148 */ |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 */ | 187 */ |
187 class CacheEntry { | 188 class CacheEntry { |
188 /** | 189 /** |
189 * The index of the flag indicating whether the source was explicitly added to | 190 * The index of the flag indicating whether the source was explicitly added to |
190 * the context or whether the source was implicitly added because it was | 191 * the context or whether the source was implicitly added because it was |
191 * referenced by another source. | 192 * referenced by another source. |
192 */ | 193 */ |
193 static int _EXPLICITLY_ADDED_FLAG = 0; | 194 static int _EXPLICITLY_ADDED_FLAG = 0; |
194 | 195 |
195 /** | 196 /** |
| 197 * The target this entry is about. |
| 198 */ |
| 199 final AnalysisTarget target; |
| 200 |
| 201 /** |
196 * The partition that is responsible for this entry. | 202 * The partition that is responsible for this entry. |
197 */ | 203 */ |
198 CachePartition _partition; | 204 CachePartition _partition; |
199 | 205 |
200 /** | 206 /** |
201 * The target this entry is about. | |
202 */ | |
203 AnalysisTarget _target; | |
204 | |
205 /** | |
206 * The most recent time at which the state of the target matched the state | 207 * The most recent time at which the state of the target matched the state |
207 * represented by this entry. | 208 * represented by this entry. |
208 */ | 209 */ |
209 int modificationTime = 0; | 210 int modificationTime = 0; |
210 | 211 |
211 /** | 212 /** |
212 * The exception that caused one or more values to have a state of | 213 * The exception that caused one or more values to have a state of |
213 * [CacheState.ERROR]. | 214 * [CacheState.ERROR]. |
214 */ | 215 */ |
215 CaughtException _exception; | 216 CaughtException _exception; |
216 | 217 |
217 /** | 218 /** |
218 * A bit-encoding of boolean flags associated with this entry's target. | 219 * A bit-encoding of boolean flags associated with this entry's target. |
219 */ | 220 */ |
220 int _flags = 0; | 221 int _flags = 0; |
221 | 222 |
222 /** | 223 /** |
223 * A table mapping result descriptors to the cached values of those results. | 224 * A table mapping result descriptors to the cached values of those results. |
224 */ | 225 */ |
225 Map<ResultDescriptor, ResultData> _resultMap = | 226 Map<ResultDescriptor, ResultData> _resultMap = |
226 new HashMap<ResultDescriptor, ResultData>(); | 227 new HashMap<ResultDescriptor, ResultData>(); |
227 | 228 |
| 229 CacheEntry(this.target); |
| 230 |
228 /** | 231 /** |
229 * The exception that caused one or more values to have a state of | 232 * The exception that caused one or more values to have a state of |
230 * [CacheState.ERROR]. | 233 * [CacheState.ERROR]. |
231 */ | 234 */ |
232 CaughtException get exception => _exception; | 235 CaughtException get exception => _exception; |
233 | 236 |
234 /** | 237 /** |
235 * Return `true` if the source was explicitly added to the context or `false` | 238 * Return `true` if the source was explicitly added to the context or `false` |
236 * if the source was implicitly added because it was referenced by another | 239 * if the source was implicitly added because it was referenced by another |
237 * source. | 240 * source. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 /** | 283 /** |
281 * Return the value of the result represented by the given [descriptor], or | 284 * Return the value of the result represented by the given [descriptor], or |
282 * the default value for the result if this entry does not have a valid value. | 285 * the default value for the result if this entry does not have a valid value. |
283 */ | 286 */ |
284 /*<V>*/ dynamic /*V*/ getValue(ResultDescriptor /*<V>*/ descriptor) { | 287 /*<V>*/ dynamic /*V*/ getValue(ResultDescriptor /*<V>*/ descriptor) { |
285 ResultData data = _resultMap[descriptor]; | 288 ResultData data = _resultMap[descriptor]; |
286 if (data == null) { | 289 if (data == null) { |
287 return descriptor.defaultValue; | 290 return descriptor.defaultValue; |
288 } | 291 } |
289 if (_partition != null) { | 292 if (_partition != null) { |
290 _partition.resultAccessed(_target, descriptor); | 293 _partition.resultAccessed(target, descriptor); |
291 } | 294 } |
292 return data.value; | 295 return data.value; |
293 } | 296 } |
294 | 297 |
295 /** | 298 /** |
296 * Return `true` if the state of any data value is [CacheState.ERROR]. | 299 * Return `true` if the state of any data value is [CacheState.ERROR]. |
297 */ | 300 */ |
298 bool hasErrorState() { | 301 bool hasErrorState() { |
299 for (ResultData data in _resultMap.values) { | 302 for (ResultData data in _resultMap.values) { |
300 if (data.state == CacheState.ERROR) { | 303 if (data.state == CacheState.ERROR) { |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 } | 379 } |
377 | 380 |
378 /** | 381 /** |
379 * Set the value of the result represented by the given [descriptor] to the | 382 * Set the value of the result represented by the given [descriptor] to the |
380 * given [value]. The optional [memento] may help to recompute [value] more | 383 * given [value]. The optional [memento] may help to recompute [value] more |
381 * efficiently after invalidation. | 384 * efficiently after invalidation. |
382 */ | 385 */ |
383 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ | 386 /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ |
384 value, List<TargetedResult> dependedOn, Object memento) { | 387 value, List<TargetedResult> dependedOn, Object memento) { |
385 _validateStateChange(descriptor, CacheState.VALID); | 388 _validateStateChange(descriptor, CacheState.VALID); |
386 TargetedResult thisResult = new TargetedResult(_target, descriptor); | 389 TargetedResult thisResult = new TargetedResult(target, descriptor); |
387 if (_partition != null) { | 390 if (_partition != null) { |
388 _partition.resultStored(thisResult, value); | 391 _partition.resultStored(thisResult, value); |
389 } | 392 } |
390 _invalidate(descriptor, null); | 393 _invalidate(descriptor, null); |
391 ResultData data = _getResultData(descriptor); | 394 ResultData data = _getResultData(descriptor); |
392 _setDependedOnResults(data, thisResult, dependedOn); | 395 _setDependedOnResults(data, thisResult, dependedOn); |
393 data.state = CacheState.VALID; | 396 data.state = CacheState.VALID; |
394 data.value = value == null ? descriptor.defaultValue : value; | 397 data.value = value == null ? descriptor.defaultValue : value; |
395 data.memento = memento; | 398 data.memento = memento; |
396 } | 399 } |
(...skipping 26 matching lines...) Expand all Loading... |
423 ResultData thisData = _getResultData(descriptor); | 426 ResultData thisData = _getResultData(descriptor); |
424 // Invalidate this result. | 427 // Invalidate this result. |
425 if (exception == null) { | 428 if (exception == null) { |
426 thisData.state = CacheState.INVALID; | 429 thisData.state = CacheState.INVALID; |
427 } else { | 430 } else { |
428 thisData.state = CacheState.ERROR; | 431 thisData.state = CacheState.ERROR; |
429 _exception = exception; | 432 _exception = exception; |
430 } | 433 } |
431 thisData.value = descriptor.defaultValue; | 434 thisData.value = descriptor.defaultValue; |
432 // Stop depending on other results. | 435 // Stop depending on other results. |
433 TargetedResult thisResult = new TargetedResult(_target, descriptor); | 436 TargetedResult thisResult = new TargetedResult(target, descriptor); |
434 List<TargetedResult> dependedOnResults = thisData.dependedOnResults; | 437 List<TargetedResult> dependedOnResults = thisData.dependedOnResults; |
435 thisData.dependedOnResults = <TargetedResult>[]; | 438 thisData.dependedOnResults = <TargetedResult>[]; |
436 dependedOnResults.forEach((TargetedResult dependedOnResult) { | 439 dependedOnResults.forEach((TargetedResult dependedOnResult) { |
437 ResultData data = _partition._getDataFor(dependedOnResult); | 440 ResultData data = _partition._getDataFor(dependedOnResult); |
438 data.dependentResults.remove(thisResult); | 441 data.dependentResults.remove(thisResult); |
439 }); | 442 }); |
440 // Invalidate results that depend on this result. | 443 // Invalidate results that depend on this result. |
441 List<TargetedResult> dependentResults = thisData.dependentResults; | 444 List<TargetedResult> dependentResults = thisData.dependentResults; |
442 thisData.dependentResults = <TargetedResult>[]; | 445 thisData.dependentResults = <TargetedResult>[]; |
443 dependentResults.forEach((TargetedResult dependentResult) { | 446 dependentResults.forEach((TargetedResult dependentResult) { |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 CacheEntry get(AnalysisTarget target) => _targetMap[target]; | 688 CacheEntry get(AnalysisTarget target) => _targetMap[target]; |
686 | 689 |
687 /** | 690 /** |
688 * Return an iterator returning all of the map entries mapping targets to | 691 * Return an iterator returning all of the map entries mapping targets to |
689 * cache entries. | 692 * cache entries. |
690 */ | 693 */ |
691 MapIterator<AnalysisTarget, CacheEntry> iterator() => | 694 MapIterator<AnalysisTarget, CacheEntry> iterator() => |
692 new SingleMapIterator<AnalysisTarget, CacheEntry>(_targetMap); | 695 new SingleMapIterator<AnalysisTarget, CacheEntry>(_targetMap); |
693 | 696 |
694 /** | 697 /** |
695 * Associate the given [entry] with the given [target]. | 698 * Puts the given [entry] into the partition. |
696 */ | 699 */ |
697 void put(AnalysisTarget target, CacheEntry entry) { | 700 void put(CacheEntry entry) { |
| 701 AnalysisTarget target = entry.target; |
698 if (entry._partition != null) { | 702 if (entry._partition != null) { |
699 throw new StateError( | 703 throw new StateError( |
700 'The entry for $target is already in ${entry._partition}'); | 704 'The entry for $target is already in ${entry._partition}'); |
701 } | 705 } |
702 entry._partition = this; | 706 entry._partition = this; |
703 entry._target = target; | |
704 entry.fixExceptionState(); | 707 entry.fixExceptionState(); |
705 _targetMap[target] = entry; | 708 _targetMap[target] = entry; |
706 } | 709 } |
707 | 710 |
708 /** | 711 /** |
709 * Remove all information related to the given [target] from this cache. | 712 * Remove all information related to the given [target] from this cache. |
710 */ | 713 */ |
711 void remove(AnalysisTarget target) { | 714 void remove(AnalysisTarget target) { |
712 for (CacheFlushManager flushManager in _flushManagerMap.values) { | 715 for (CacheFlushManager flushManager in _flushManagerMap.values) { |
713 flushManager.targetRemoved(target); | 716 flushManager.targetRemoved(target); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 class UniversalCachePartition extends CachePartition { | 888 class UniversalCachePartition extends CachePartition { |
886 /** | 889 /** |
887 * Initialize a newly created cache partition, belonging to the given | 890 * Initialize a newly created cache partition, belonging to the given |
888 * [context]. | 891 * [context]. |
889 */ | 892 */ |
890 UniversalCachePartition(InternalAnalysisContext context) : super(context); | 893 UniversalCachePartition(InternalAnalysisContext context) : super(context); |
891 | 894 |
892 @override | 895 @override |
893 bool isResponsibleFor(AnalysisTarget target) => true; | 896 bool isResponsibleFor(AnalysisTarget target) => true; |
894 } | 897 } |
OLD | NEW |