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 5ae41bd5b0ff5448bd6db22ec162dd336af56ee7..a0398e27e4e12dcd15ab28c5e5ff4fc15790dd0e 100644 |
| --- a/pkg/analyzer/lib/src/context/cache.dart |
| +++ b/pkg/analyzer/lib/src/context/cache.dart |
| @@ -6,10 +6,8 @@ library analyzer.src.context.cache; |
| import 'dart:collection'; |
| -import 'package:analyzer/src/generated/ast.dart'; |
| import 'package:analyzer/src/generated/engine.dart' |
| show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority; |
| -import 'package:analyzer/src/generated/html.dart'; |
| import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| import 'package:analyzer/src/generated/utilities_collection.dart'; |
| @@ -17,6 +15,11 @@ import 'package:analyzer/src/generated/utilities_general.dart'; |
| import 'package:analyzer/task/model.dart'; |
| /** |
| + * Return `true` if the given [target] is a priority one. |
| + */ |
| +typedef bool IsPriorityAnalysisTarget(AnalysisTarget target); |
| + |
| +/** |
| * An LRU cache of results produced by analysis. |
| */ |
| class AnalysisCache { |
| @@ -37,13 +40,11 @@ class AnalysisCache { |
| * so the most specific partition (usually an [SdkCachePartition]) should be |
| * first and the most general (usually a [UniversalCachePartition]) last. |
| */ |
| - AnalysisCache(this._partitions); |
| - |
| - /** |
| - * Return the number of entries in this cache that have an AST associated with |
| - * them. |
| - */ |
| - int get astSize => _partitions[_partitions.length - 1].astSize; |
| + AnalysisCache(this._partitions) { |
| + for (CachePartition partition in _partitions) { |
| + partition._cache = this; |
| + } |
| + } |
| // TODO(brianwilkerson) Implement or delete this. |
| // /** |
| @@ -63,22 +64,6 @@ class AnalysisCache { |
| // } |
| /** |
| - * Record that the AST associated with the given [target] was just read from |
| - * the cache. |
| - */ |
| - void accessedAst(AnalysisTarget target) { |
| - // TODO(brianwilkerson) Extract this logic to a helper method (here and |
| - // elsewhere) |
| - int count = _partitions.length; |
| - for (int i = 0; i < count; i++) { |
| - if (_partitions[i].contains(target)) { |
| - _partitions[i].accessedAst(target); |
| - return; |
| - } |
| - } |
| - } |
| - |
| - /** |
| * Return the entry associated with the given [target]. |
| */ |
| CacheEntry get(AnalysisTarget target) { |
| @@ -135,8 +120,6 @@ class AnalysisCache { |
| * Associate the given [entry] with the given [target]. |
| */ |
| void put(AnalysisTarget target, CacheEntry entry) { |
| - entry._cache = this; |
| - entry._target = target; |
| entry.fixExceptionState(); |
| int count = _partitions.length; |
| for (int i = 0; i < count; i++) { |
| @@ -178,20 +161,6 @@ class AnalysisCache { |
| } |
| /** |
| - * Record that the AST associated with the given [target] was just removed |
| - * from the cache. |
| - */ |
| - void removedAst(AnalysisTarget target) { |
| - int count = _partitions.length; |
| - for (int i = 0; i < count; i++) { |
| - if (_partitions[i].contains(target)) { |
| - _partitions[i].removedAst(target); |
| - return; |
| - } |
| - } |
| - } |
| - |
| - /** |
| * Return the number of targets that are mapped to cache entries. |
| */ |
| int size() { |
| @@ -203,20 +172,6 @@ class AnalysisCache { |
| return size; |
| } |
| - /** |
| - * Record that the AST associated with the given [target] was just stored to |
| - * the cache. |
| - */ |
| - void storedAst(AnalysisTarget target) { |
| - int count = _partitions.length; |
| - for (int i = 0; i < count; i++) { |
| - if (_partitions[i].contains(target)) { |
| - _partitions[i].storedAst(target); |
| - return; |
| - } |
| - } |
| - } |
| - |
| ResultData _getDataFor(TargetedResult result) { |
| AnalysisTarget target = result.target; |
| int count = _partitions.length; |
| @@ -242,9 +197,9 @@ class CacheEntry { |
| static int _EXPLICITLY_ADDED_FLAG = 0; |
| /** |
| - * The cache that contains this entry. |
| + * The partition that is responsible for this entry. |
| */ |
| - AnalysisCache _cache; |
| + CachePartition _partition; |
| /** |
| * The target this entry is about. |
| @@ -296,19 +251,6 @@ class CacheEntry { |
| } |
| /** |
| - * Return `true` if this entry contains at least one result whose value is an |
| - * AST structure. |
| - */ |
| - bool get hasAstStructure { |
| - for (ResultData data in _resultMap.values) { |
| - if (data.value is AstNode || data.value is XmlNode) { |
| - return true; |
| - } |
| - } |
| - return false; |
| - } |
| - |
| - /** |
| * Fix the state of the [exception] to match the current state of the entry. |
| */ |
| void fixExceptionState() { |
| @@ -318,19 +260,6 @@ class CacheEntry { |
| } |
| /** |
| - * Mark any AST structures associated with this cache entry as being flushed. |
| - */ |
| - void flushAstStructures() { |
| - _resultMap.forEach((ResultDescriptor descriptor, ResultData data) { |
| - if (data.value is AstNode || data.value is XmlNode) { |
| - _validateStateChange(descriptor, CacheState.FLUSHED); |
| - data.state = CacheState.FLUSHED; |
| - data.value = descriptor.defaultValue; |
| - } |
| - }); |
| - } |
| - |
| - /** |
| * Return the memento of the result represented by the given [descriptor]. |
| */ |
| Object getMemento(ResultDescriptor descriptor) { |
| @@ -361,6 +290,9 @@ class CacheEntry { |
| if (data == null) { |
| return descriptor.defaultValue; |
| } |
| + if (_partition != null) { |
| + _partition.resultAccessed(_target, descriptor); |
| + } |
| return data.value; |
| } |
| @@ -415,7 +347,7 @@ class CacheEntry { |
| for (ResultDescriptor descriptor in descriptors) { |
| ResultData data = _getResultData(descriptor); |
| TargetedResult thisResult = new TargetedResult(_target, descriptor); |
| - data.invalidate(_cache, thisResult, CacheState.ERROR); |
| + data.invalidate(_partition, thisResult, CacheState.ERROR); |
| } |
| } |
| @@ -435,7 +367,7 @@ class CacheEntry { |
| ResultData data = _resultMap[descriptor]; |
| if (data != null) { |
| TargetedResult thisResult = new TargetedResult(_target, descriptor); |
| - data.invalidate(_cache, thisResult, CacheState.INVALID); |
| + data.invalidate(_partition, thisResult, CacheState.INVALID); |
| } |
| } else { |
| ResultData data = _getResultData(descriptor); |
| @@ -458,12 +390,13 @@ class CacheEntry { |
| /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/ |
| value, List<TargetedResult> dependedOn, Object memento) { |
| _validateStateChange(descriptor, CacheState.VALID); |
| - ResultData data = _getResultData(descriptor); |
| - { |
| - TargetedResult thisResult = new TargetedResult(_target, descriptor); |
| - data.invalidate(_cache, thisResult, CacheState.INVALID); |
| - data.setDependedOnResults(_cache, thisResult, dependedOn); |
| + TargetedResult thisResult = new TargetedResult(_target, descriptor); |
| + if (_partition != null) { |
| + _partition.resultStored(thisResult, value); |
| } |
| + ResultData data = _getResultData(descriptor); |
| + data.invalidate(_partition, thisResult, CacheState.INVALID); |
| + data.setDependedOnResults(_partition, thisResult, dependedOn); |
| data.state = CacheState.VALID; |
| data.value = value == null ? descriptor.defaultValue : value; |
| data.memento = memento; |
| @@ -540,108 +473,176 @@ class CacheEntry { |
| } |
| /** |
| - * A single partition in an LRU cache of information related to analysis. |
| + * An object that controls flushing of analysis results from the cache. |
| */ |
| -abstract class CachePartition { |
| - /** |
| - * The context that owns this partition. Multiple contexts can reference a |
| - * partition, but only one context can own it. |
| - */ |
| - final InternalAnalysisContext context; |
| +class CacheFlushManager<T> { |
| + final IsPriorityAnalysisTarget isPriorityAnalysisTarget; |
| + final ResultCachingPolicy<T> policy; |
| + final int maxActiveSize; |
| + final int maxIdleSize; |
| /** |
| - * The maximum number of sources for which AST structures should be kept in |
| - * the cache. |
| + * A map of the stored [TargetedResult] to their sizes. |
| */ |
| - int _maxCacheSize = 0; |
| + final HashMap<TargetedResult, int> resultSizeMap = |
| + new HashMap<TargetedResult, int>(); |
| /** |
| - * The policy used to determine which results to remove from the cache. |
| + * A linked set containing the most recently accessed results with the most |
| + * recently used at the end of the list. When more results are added than the |
| + * maximum size allowed then the least recently used results will be flushed |
| + * from the cache. |
| */ |
| - final CacheRetentionPolicy _retentionPolicy; |
| + final LinkedHashSet<TargetedResult> recentlyUsed = |
| + new LinkedHashSet<TargetedResult>(); |
| /** |
| - * A table mapping the targets belonging to this partition to the information |
| - * known about those targets. |
| + * The current size of stored results. |
| */ |
| - HashMap<AnalysisTarget, CacheEntry> _targetMap = |
| - new HashMap<AnalysisTarget, CacheEntry>(); |
| + int currentSize = 0; |
| /** |
| - * A list containing the most recently accessed targets with the most recently |
| - * used at the end of the list. When more targets are added than the maximum |
| - * allowed then the least recently used target will be removed and will have |
| - * it's cached AST structure flushed. |
| + * The current maximum cache size. |
| */ |
| - List<AnalysisTarget> _recentlyUsed = <AnalysisTarget>[]; |
| + int maxSize; |
| - /** |
| - * Initialize a newly created cache partition, belonging to the given |
| - * [context]. The partition will maintain at most [_maxCacheSize] AST |
| - * structures in the cache, using the [_retentionPolicy] to determine which |
| - * AST structures to flush. |
| - */ |
| - CachePartition(this.context, this._maxCacheSize, this._retentionPolicy); |
| + CacheFlushManager( |
| + ResultCachingPolicy<T> policy, this.isPriorityAnalysisTarget) |
| + : policy = policy, |
| + maxActiveSize = policy.maxActiveSize, |
| + maxIdleSize = policy.maxIdleSize, |
| + maxSize = policy.maxIdleSize; |
| /** |
| - * Return the number of entries in this partition that have an AST associated |
| - * with them. |
| + * If [currentSize] is already less than [maxSize], returns an empty list. |
| + * Otherwise returns [TargetedResult]s to flush from the cache to make |
| + * [currentSize] lass then [maxSize]. |
|
Brian Wilkerson
2015/05/07 14:19:19
"lass then" --> "less than"
If it's intentional t
scheglov
2015/05/07 15:49:27
Done.
|
| */ |
| - int get astSize { |
| - int astSize = 0; |
| - int count = _recentlyUsed.length; |
| - for (int i = 0; i < count; i++) { |
| - AnalysisTarget target = _recentlyUsed[i]; |
| - CacheEntry entry = _targetMap[target]; |
| - if (entry.hasAstStructure) { |
| - astSize++; |
| + List<TargetedResult> flushToSize() { |
| + // If still under the cap, done. |
| + if (maxSize == -1 || currentSize <= maxSize) { |
| + return TargetedResult.EMPTY_LIST; |
| + } |
| + // Flush results until we are under the cap. |
| + List<TargetedResult> resultsToFlush = <TargetedResult>[]; |
| + for (TargetedResult result in recentlyUsed) { |
| + if (isPriorityAnalysisTarget(result.target)) { |
| + continue; |
| + } |
| + resultsToFlush.add(result); |
| + int size = resultSizeMap.remove(result); |
| + assert(size != null); |
| + currentSize -= size; |
| + if (currentSize <= maxSize) { |
| + break; |
| } |
| } |
| - return astSize; |
| + recentlyUsed.removeAll(resultsToFlush); |
| + return resultsToFlush; |
| } |
| /** |
| - * Return a table mapping the targets known to the context to the information |
| - * known about the target. |
| - * |
| - * <b>Note:</b> This method is only visible for use by [AnalysisCache] and |
| - * should not be used for any other purpose. |
| + * Notifies this manager that the corresponding analysis context is acive. |
|
Brian Wilkerson
2015/05/07 14:19:19
"acive" --> "active"
scheglov
2015/05/07 15:49:27
Done.
|
| */ |
| - Map<AnalysisTarget, CacheEntry> get map => _targetMap; |
| + void madeActive() { |
| + maxSize = maxActiveSize; |
| + } |
| /** |
| - * Return the maximum size of the cache. |
| + * Notifies this manager that the corresponding analysis context is idle. |
| + * Returns [TargetedResult]s that should be flushed from the cache. |
| */ |
| - int get maxCacheSize => _maxCacheSize; |
| + List<TargetedResult> madeIdle() { |
| + maxSize = maxIdleSize; |
| + return flushToSize(); |
| + } |
| /** |
| - * Set the maximum size of the cache to the given [size]. |
| + * Records that the given [result] was just read from the cache. |
| */ |
| - void set maxCacheSize(int size) { |
| - _maxCacheSize = size; |
| - while (_recentlyUsed.length > _maxCacheSize) { |
| - if (!_flushAstFromCache()) { |
| - break; |
| - } |
| + void resultAccessed(TargetedResult result) { |
| + if (recentlyUsed.remove(result)) { |
| + recentlyUsed.add(result); |
|
Brian Wilkerson
2015/05/07 14:19:19
Given that an access is a use, shouldn't the resul
scheglov
2015/05/07 15:49:27
Yes, access is a use, but only if the result was a
|
| } |
| } |
| /** |
| - * Record that the AST associated with the given [target] was just read from |
| - * the cache. |
| + * Records that the given [newResult] and [newValue] were stored to the cache. |
| + * Returns [TargetedResult]s that should be flushed from the cache. |
| */ |
| - void accessedAst(AnalysisTarget target) { |
| - if (_recentlyUsed.remove(target)) { |
| - _recentlyUsed.add(target); |
| - return; |
| + List<TargetedResult> resultStored(TargetedResult newResult, T newValue) { |
| + if (!recentlyUsed.remove(newResult)) { |
| + int size = policy.measure(newValue); |
| + resultSizeMap[newResult] = size; |
| + currentSize += size; |
| } |
| - while (_recentlyUsed.length >= _maxCacheSize) { |
| - if (!_flushAstFromCache()) { |
| - break; |
| + recentlyUsed.add(newResult); |
| + return flushToSize(); |
| + } |
| + |
| + /** |
| + * Records that the given [target] was just removed from to the cache. |
| + */ |
| + void targetRemoved(AnalysisTarget target) { |
| + List<TargetedResult> resultsToRemove = <TargetedResult>[]; |
| + for (TargetedResult result in recentlyUsed) { |
| + if (result.target == target) { |
| + resultsToRemove.add(result); |
| + int size = resultSizeMap.remove(result); |
| + assert(size != null); |
| + currentSize -= size; |
| } |
| } |
| - _recentlyUsed.add(target); |
| + recentlyUsed.removeAll(resultsToRemove); |
| } |
| +} |
| + |
| +/** |
| + * A single partition in an LRU cache of information related to analysis. |
| + */ |
| +abstract class CachePartition { |
| + /** |
| + * The [AnalysisCache] that owns this partition. |
| + * |
| + * TODO(scheglov) It seems wrong. Partitions may be shared between caches. |
| + * But we need a way to go from every "enclosing" partition into "enclosed" |
| + * ones. |
|
Brian Wilkerson
2015/05/07 14:19:19
I'm guessing that this is effectively the same as
scheglov
2015/05/07 15:49:27
There are some problems with it in tests.
I will d
|
| + */ |
| + AnalysisCache _cache; |
| + |
| + /** |
| + * The context that owns this partition. Multiple contexts can reference a |
| + * partition, but only one context can own it. |
| + */ |
| + final InternalAnalysisContext context; |
| + |
| + /** |
| + * A table mapping caching policies to the cache flush managers. |
| + */ |
| + final HashMap<ResultCachingPolicy, CacheFlushManager> _flushManagerMap = |
| + new HashMap<ResultCachingPolicy, CacheFlushManager>(); |
| + |
| + /** |
| + * A table mapping the targets belonging to this partition to the information |
| + * known about those targets. |
| + */ |
| + HashMap<AnalysisTarget, CacheEntry> _targetMap = |
| + new HashMap<AnalysisTarget, CacheEntry>(); |
| + |
| + /** |
| + * Initialize a newly created cache partition, belonging to the given |
| + * [context]. |
| + */ |
| + CachePartition(this.context); |
| + |
| + /** |
| + * Return a table mapping the targets known to the context to the information |
| + * known about the target. |
| + * |
| + * <b>Note:</b> This method is only visible for use by [AnalysisCache] and |
| + * should not be used for any other purpose. |
| + */ |
| + Map<AnalysisTarget, CacheEntry> get map => _targetMap; |
| /** |
| * Return `true` if the given [target] is contained in this partition. |
| @@ -666,6 +667,8 @@ abstract class CachePartition { |
| * Associate the given [entry] with the given [target]. |
| */ |
| void put(AnalysisTarget target, CacheEntry entry) { |
| + entry._partition = this; |
|
Brian Wilkerson
2015/05/07 14:19:19
It would be good to ensure that "entry._partition"
scheglov
2015/05/07 15:49:27
Done.
|
| + entry._target = target; |
|
Brian Wilkerson
2015/05/07 14:19:19
It seems strange to assign the target here. It wou
scheglov
2015/05/07 15:49:27
Yes.
Probably more natural would be to make target
|
| entry.fixExceptionState(); |
| _targetMap[target] = entry; |
| } |
| @@ -674,140 +677,56 @@ abstract class CachePartition { |
| * Remove all information related to the given [target] from this cache. |
| */ |
| void remove(AnalysisTarget target) { |
| - _recentlyUsed.remove(target); |
| + for (CacheFlushManager flushManager in _flushManagerMap.values) { |
| + flushManager.targetRemoved(target); |
| + } |
| _targetMap.remove(target); |
| } |
| /** |
| - * Record that the AST associated with the given [target] was just removed |
| - * from the cache. |
| - */ |
| - void removedAst(AnalysisTarget target) { |
| - _recentlyUsed.remove(target); |
| - } |
| - |
| - /** |
| - * Return the number of targets that are mapped to cache entries. |
| - */ |
| - int size() => _targetMap.length; |
| - |
| - /** |
| - * Record that the AST associated with the given [target] was just stored to |
| - * the cache. |
| + * Records that a value of the result described by the given [descriptor] |
| + * for the given [target] was just read from the cache. |
| */ |
| - void storedAst(AnalysisTarget target) { |
| - if (_recentlyUsed.contains(target)) { |
| - return; |
| - } |
| - while (_recentlyUsed.length >= _maxCacheSize) { |
| - if (!_flushAstFromCache()) { |
| - break; |
| - } |
| - } |
| - _recentlyUsed.add(target); |
| + void resultAccessed(AnalysisTarget target, ResultDescriptor descriptor) { |
| + CacheFlushManager flushManager = _getFlushManager(descriptor); |
| + TargetedResult result = new TargetedResult(target, descriptor); |
| + flushManager.resultAccessed(result); |
| } |
| /** |
| - * Attempt to flush one AST structure from the cache. Return `true` if a |
| - * structure was flushed. |
| + * Records that the given [result] was just stored into the cache. |
| */ |
| - bool _flushAstFromCache() { |
| - AnalysisTarget removedTarget = _removeAstToFlush(); |
| - if (removedTarget == null) { |
| - return false; |
| + void resultStored(TargetedResult result, Object value) { |
| + CacheFlushManager flushManager = _getFlushManager(result.result); |
| + List<TargetedResult> resultsToFlush = |
| + flushManager.resultStored(result, value); |
| + for (TargetedResult result in resultsToFlush) { |
| + CacheEntry entry = get(result.target); |
| + ResultData data = entry._resultMap[result.result]; |
| + data.flush(); |
| } |
| - CacheEntry entry = _targetMap[removedTarget]; |
| - entry.flushAstStructures(); |
| - return true; |
| - } |
| - |
| - /** |
| - * Remove and return one target from the list of recently used targets whose |
| - * AST structure can be flushed from the cache, or `null` if none of the |
| - * targets can be removed. The target that will be returned will be the target |
| - * that has been unreferenced for the longest period of time but that is not a |
| - * priority for analysis. |
| - */ |
| - AnalysisTarget _removeAstToFlush() { |
| - int targetToRemove = -1; |
| - for (int i = 0; i < _recentlyUsed.length; i++) { |
| - AnalysisTarget target = _recentlyUsed[i]; |
| - RetentionPriority priority = |
| - _retentionPolicy.getAstPriority(target, _targetMap[target]); |
| - if (priority == RetentionPriority.LOW) { |
| - return _recentlyUsed.removeAt(i); |
| - } else if (priority == RetentionPriority.MEDIUM && targetToRemove < 0) { |
| - targetToRemove = i; |
| - } |
| - } |
| - if (targetToRemove < 0) { |
| - // This happens if the retention policy returns a priority of HIGH for all |
| - // of the targets that have been recently used. This is the case, for |
| - // example, when the list of priority sources is bigger than the current |
| - // cache size. |
| - return null; |
| - } |
| - return _recentlyUsed.removeAt(targetToRemove); |
| } |
| -} |
| -/** |
| - * A policy objecy that determines how important it is for data to be retained |
| - * in the analysis cache. |
| - */ |
| -abstract class CacheRetentionPolicy { |
| /** |
| - * Return the priority of retaining the AST structure for the given [target] |
| - * in the given [entry]. |
| + * Return the number of targets that are mapped to cache entries. |
| */ |
| - // TODO(brianwilkerson) Find a more general mechanism, probably based on task |
| - // descriptors, to determine which data is still needed for analysis and which |
| - // can be removed from the cache. Ideally we could (a) remove the need for |
| - // this class and (b) be able to flush all result data (not just AST's). |
| - RetentionPriority getAstPriority(AnalysisTarget target, CacheEntry entry); |
| -} |
| + int size() => _targetMap.length; |
| -/** |
| - * A retention policy that will keep AST's in the cache if there is analysis |
| - * information that needs to be computed for a source, where the computation is |
| - * dependent on having the AST. |
| - */ |
| -class DefaultRetentionPolicy implements CacheRetentionPolicy { |
| - /** |
| - * An instance of this class that can be shared. |
| - */ |
| - static const DefaultRetentionPolicy POLICY = const DefaultRetentionPolicy(); |
| + ResultData _getDataFor(TargetedResult result) { |
| + return _cache._getDataFor(result); |
| + } |
| /** |
| - * Initialize a newly created instance of this class. |
| + * Return the [CacheFlushManager] for the given [descriptor], not `null`. |
| */ |
| - const DefaultRetentionPolicy(); |
| - |
| - // TODO(brianwilkerson) Implement or delete this. |
| -// /** |
| -// * Return `true` if there is analysis information in the given entry that needs to be |
| -// * computed, where the computation is dependent on having the AST. |
| -// * |
| -// * @param dartEntry the entry being tested |
| -// * @return `true` if there is analysis information that needs to be computed from the AST |
| -// */ |
| -// bool astIsNeeded(DartEntry dartEntry) => |
| -// dartEntry.hasInvalidData(DartEntry.HINTS) || |
| -// dartEntry.hasInvalidData(DartEntry.LINTS) || |
| -// dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) || |
| -// dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS); |
| + CacheFlushManager _getFlushManager(ResultDescriptor descriptor) { |
| + ResultCachingPolicy policy = descriptor.cachingPolicy; |
| + return _flushManagerMap.putIfAbsent( |
| + policy, () => new CacheFlushManager(policy, _isPriorityAnalysisTarget)); |
| + } |
| - @override |
| - RetentionPriority getAstPriority(AnalysisTarget target, CacheEntry entry) { |
| - // TODO(brianwilkerson) Implement or replace this. |
| -// if (sourceEntry is DartEntry) { |
| -// DartEntry dartEntry = sourceEntry; |
| -// if (astIsNeeded(dartEntry)) { |
| -// return RetentionPriority.MEDIUM; |
| -// } |
| -// } |
| -// return RetentionPriority.LOW; |
| - return RetentionPriority.MEDIUM; |
| + bool _isPriorityAnalysisTarget(AnalysisTarget target) { |
| + return context.priorityTargets.contains(target); |
| } |
| } |
| @@ -866,11 +785,19 @@ class ResultData { |
| } |
| /** |
| + * Flush this value. |
| + */ |
| + void flush() { |
| + state = CacheState.FLUSHED; |
| + value = descriptor.defaultValue; |
| + } |
| + |
| + /** |
| * Invalidate this [ResultData] that corresponds to [thisResult] and |
| * propagate invalidation to the results that depend on this one. |
| */ |
| - void invalidate( |
| - AnalysisCache cache, TargetedResult thisResult, CacheState newState) { |
| + void invalidate(CachePartition partition, TargetedResult thisResult, |
| + CacheState newState) { |
| // Invalidate this result. |
| state = newState; |
| value = descriptor.defaultValue; |
| @@ -878,15 +805,15 @@ class ResultData { |
| List<TargetedResult> dependedOnResults = this.dependedOnResults; |
| this.dependedOnResults = <TargetedResult>[]; |
| dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| - ResultData data = cache._getDataFor(dependedOnResult); |
| + ResultData data = partition._getDataFor(dependedOnResult); |
| data.removeDependentResult(thisResult); |
| }); |
| // Invalidate results that depend on this result. |
| List<TargetedResult> dependentResults = this.dependentResults; |
| this.dependentResults = <TargetedResult>[]; |
| dependentResults.forEach((TargetedResult dependentResult) { |
| - ResultData data = cache._getDataFor(dependentResult); |
| - data.invalidate(cache, dependentResult, newState); |
| + ResultData data = partition._getDataFor(dependentResult); |
| + data.invalidate(partition, dependentResult, newState); |
| }); |
| } |
| @@ -900,15 +827,15 @@ class ResultData { |
| /** |
| * Set the [dependedOn] on which this result depends. |
| */ |
| - void setDependedOnResults(AnalysisCache cache, TargetedResult thisResult, |
| + void setDependedOnResults(CachePartition partition, TargetedResult thisResult, |
| List<TargetedResult> dependedOn) { |
| dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| - ResultData data = cache._getDataFor(dependedOnResult); |
| + ResultData data = partition._getDataFor(dependedOnResult); |
| data.removeDependentResult(thisResult); |
| }); |
| dependedOnResults = dependedOn; |
| dependedOnResults.forEach((TargetedResult dependentResult) { |
| - ResultData data = cache._getDataFor(dependentResult); |
| + ResultData data = partition._getDataFor(dependentResult); |
| data.addDependentResult(thisResult); |
| }); |
| } |
| @@ -920,11 +847,9 @@ class ResultData { |
| class SdkCachePartition extends CachePartition { |
| /** |
| * Initialize a newly created cache partition, belonging to the given |
| - * [context]. The partition will maintain at most [maxCacheSize] AST |
| - * structures in the cache. |
| + * [context]. |
| */ |
| - SdkCachePartition(InternalAnalysisContext context, int maxCacheSize) |
| - : super(context, maxCacheSize, DefaultRetentionPolicy.POLICY); |
| + SdkCachePartition(InternalAnalysisContext context) : super(context); |
| @override |
| bool contains(AnalysisTarget target) { |
| @@ -979,13 +904,9 @@ class TargetedResult { |
| class UniversalCachePartition extends CachePartition { |
| /** |
| * Initialize a newly created cache partition, belonging to the given |
| - * [context]. The partition will maintain at most [maxCacheSize] AST |
| - * structures in the cache, using the [retentionPolicy] to determine which |
| - * AST structures to flush. |
| + * [context]. |
| */ |
| - UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize, |
| - CacheRetentionPolicy retentionPolicy) |
| - : super(context, maxCacheSize, retentionPolicy); |
| + UniversalCachePartition(InternalAnalysisContext context) : super(context); |
| @override |
| bool contains(AnalysisTarget target) => true; |