| 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..cb756991194215bc10717cb9ee8e30c78a25f67c 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,179 @@ 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.
|
| - */
|
| - 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++;
|
| + * If [currentSize] is already less than [maxSize], returns an empty list.
|
| + * Otherwise returns [TargetedResult]s to flush from the cache to make
|
| + * [currentSize] less or equal to [maxSize].
|
| + *
|
| + * Results for priority files are never flushed, so this method might leave
|
| + * [currentSize] greater than [maxSize].
|
| + */
|
| + 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 active.
|
| */
|
| - 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);
|
| }
|
| }
|
|
|
| /**
|
| - * 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.
|
| + */
|
| + 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 +670,12 @@ abstract class CachePartition {
|
| * Associate the given [entry] with the given [target].
|
| */
|
| void put(AnalysisTarget target, CacheEntry entry) {
|
| + if (entry._partition != null) {
|
| + throw new StateError(
|
| + 'The entry for $target is already in ${entry._partition}');
|
| + }
|
| + entry._partition = this;
|
| + entry._target = target;
|
| entry.fixExceptionState();
|
| _targetMap[target] = entry;
|
| }
|
| @@ -674,140 +684,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.
|
| + * Records that a value of the result described by the given [descriptor]
|
| + * for the given [target] was just read from the cache.
|
| */
|
| - void removedAst(AnalysisTarget target) {
|
| - _recentlyUsed.remove(target);
|
| + void resultAccessed(AnalysisTarget target, ResultDescriptor descriptor) {
|
| + CacheFlushManager flushManager = _getFlushManager(descriptor);
|
| + TargetedResult result = new TargetedResult(target, descriptor);
|
| + flushManager.resultAccessed(result);
|
| }
|
|
|
| /**
|
| - * 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 the given [result] was just stored into the cache.
|
| */
|
| - void storedAst(AnalysisTarget target) {
|
| - if (_recentlyUsed.contains(target)) {
|
| - return;
|
| - }
|
| - while (_recentlyUsed.length >= _maxCacheSize) {
|
| - if (!_flushAstFromCache()) {
|
| - break;
|
| - }
|
| + 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();
|
| }
|
| - _recentlyUsed.add(target);
|
| }
|
|
|
| /**
|
| - * Attempt to flush one AST structure from the cache. Return `true` if a
|
| - * structure was flushed.
|
| - */
|
| - bool _flushAstFromCache() {
|
| - AnalysisTarget removedTarget = _removeAstToFlush();
|
| - if (removedTarget == null) {
|
| - return false;
|
| - }
|
| - 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 +792,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 +812,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 +834,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 +854,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 +911,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;
|
|
|