| 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 |