Chromium Code Reviews| Index: pkg/analyzer/lib/src/context/cache.dart |
| diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart |
| index 01ae4ea85bf5ab9bcf220494b364339ab7e38d20..edb223159fe9f81315bb0321ca72cb714be81475 100644 |
| --- a/pkg/analyzer/lib/src/context/cache.dart |
| +++ b/pkg/analyzer/lib/src/context/cache.dart |
| @@ -252,6 +252,11 @@ class CacheEntry { |
| static int _EXPLICITLY_ADDED_FLAG = 0; |
| /** |
| + * The next invalidation process identifier. |
| + */ |
| + static int nextInvalidateId = 0; |
| + |
| + /** |
| * The target this entry is about. |
| */ |
| final AnalysisTarget target; |
| @@ -440,7 +445,7 @@ class CacheEntry { |
| if (state == CacheState.INVALID) { |
| ResultData data = _resultMap[descriptor]; |
| if (data != null) { |
| - _invalidate(descriptor, delta); |
| + _invalidate(nextInvalidateId++, descriptor, delta, 0); |
| } |
| } else { |
| ResultData data = getResultData(descriptor); |
| @@ -490,7 +495,7 @@ class CacheEntry { |
| */ |
| void setValueIncremental(ResultDescriptor descriptor, dynamic value) { |
| ResultData data = getResultData(descriptor); |
| - _invalidateDependentResults(data, null); |
| + _invalidateDependentResults(null, data, null, 0); |
| data.state = CacheState.VALID; |
| data.value = value; |
| } |
| @@ -511,25 +516,33 @@ class CacheEntry { |
| * Invalidate the result represented by the given [descriptor] and propagate |
| * invalidation to other results that depend on it. |
| */ |
| - void _invalidate(ResultDescriptor descriptor, Delta delta) { |
| + void _invalidate( |
| + int id, ResultDescriptor descriptor, Delta delta, int level) { |
| + ResultData thisData = _resultMap[descriptor]; |
| + if (thisData == null) { |
| + return; |
| + } |
| + // Stop if already validated. |
| + if (delta != null) { |
| + if (thisData.invalidateId == id) { |
| + return; |
| + } |
| + thisData.invalidateId = id; |
| + } |
| + // Ask the delta to validate. |
| DeltaResult deltaResult = null; |
| if (delta != null) { |
| deltaResult = delta.validate(_partition.context, target, descriptor); |
| if (deltaResult == DeltaResult.STOP) { |
| -// print('not-invalidate $descriptor for $target'); |
| return; |
| } |
| } |
| -// print('invalidate $descriptor for $target'); |
| - ResultData thisData; |
| if (deltaResult == null || deltaResult == DeltaResult.INVALIDATE) { |
| - thisData = _resultMap.remove(descriptor); |
| - } |
| - if (deltaResult == DeltaResult.KEEP_CONTINUE) { |
| - thisData = _resultMap[descriptor]; |
| - } |
| - if (thisData == null) { |
| - return; |
| + _resultMap.remove(descriptor); |
| +// { |
|
Brian Wilkerson
2015/09/18 18:37:42
If you didn't intend to leave this debug code, ple
|
| +// String indent = ' ' * level; |
| +// print('[$id]$indent invalidate $descriptor for $target'); |
| +// } |
| } |
| // Stop depending on other results. |
| TargetedResult thisResult = new TargetedResult(target, descriptor); |
| @@ -540,7 +553,7 @@ class CacheEntry { |
| } |
| } |
| // Invalidate results that depend on this result. |
| - _invalidateDependentResults(thisData, delta); |
| + _invalidateDependentResults(id, thisData, delta, level + 1); |
| // If empty, remove the entry altogether. |
| if (_resultMap.isEmpty) { |
| _partition._targetMap.remove(target); |
| @@ -557,19 +570,20 @@ class CacheEntry { |
| void _invalidateAll() { |
| List<ResultDescriptor> results = _resultMap.keys.toList(); |
| for (ResultDescriptor result in results) { |
| - _invalidate(result, null); |
| + _invalidate(null, result, null, 0); |
| } |
| } |
| /** |
| * Invalidate results that depend on [thisData]. |
| */ |
| - void _invalidateDependentResults(ResultData thisData, Delta delta) { |
| + void _invalidateDependentResults( |
| + int id, ResultData thisData, Delta delta, int level) { |
| List<TargetedResult> dependentResults = thisData.dependentResults.toList(); |
| for (TargetedResult dependentResult in dependentResults) { |
| CacheEntry entry = _partition.get(dependentResult.target); |
| if (entry != null) { |
| - entry._invalidate(dependentResult.result, delta); |
| + entry._invalidate(id, dependentResult.result, delta, level); |
| } |
| } |
| } |
| @@ -1100,6 +1114,13 @@ class ResultData { |
| Object value; |
| /** |
| + * The identifier of the invalidation process that most recently checked |
| + * this value. If it is the same as the current invalidation identifier, |
| + * then there is no reason to check it (and its subtree again). |
| + */ |
| + int invalidateId = -1; |
| + |
| + /** |
| * A list of the results on which this result depends. |
| */ |
| List<TargetedResult> dependedOnResults = <TargetedResult>[]; |