Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Unified Diff: pkg/analyzer/lib/src/context/cache.dart

Issue 1121963002: Record dependencies and invalidate results. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 67e71bc411172cfeda68b4a9388778bccb8f3fa5..e21fe5d7c008862836cdb4648028f7240aaecefa 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -13,6 +13,7 @@ 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';
+import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/task/model.dart';
/**
@@ -134,6 +135,8 @@ 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++) {
@@ -213,6 +216,18 @@ class AnalysisCache {
}
}
}
+
+ ResultData _getDataFor(TargetedResult result) {
+ AnalysisTarget target = result.target;
+ int count = _partitions.length;
+ for (int i = 0; i < count; i++) {
+ if (_partitions[i].contains(target)) {
+ CacheEntry entry = _partitions[i].get(target);
+ return entry._getResultData(result.result);
+ }
+ }
+ return null;
+ }
}
/**
@@ -227,6 +242,16 @@ class CacheEntry {
static int _EXPLICITLY_ADDED_FLAG = 0;
/**
+ * The cache that contains this entry.
+ */
+ AnalysisCache _cache;
+
+ /**
+ * The target this entry is about.
+ */
+ AnalysisTarget _target;
+
+ /**
* The most recent time at which the state of the target matched the state
* represented by this entry.
*/
@@ -363,9 +388,9 @@ class CacheEntry {
getState(descriptor) == CacheState.VALID;
/**
- * Set the [CacheState.ERROR] state for given [descriptors], their values to
- * the corresponding default values, and remember the [exception] that caused
- * this state.
+ * For each of the given [descriptors], set their states to
+ * [CacheState.ERROR], their values to the corresponding default values, and
+ * remember the [exception] that caused this state.
*/
void setErrorState(
CaughtException exception, List<ResultDescriptor> descriptors) {
@@ -378,6 +403,7 @@ class CacheEntry {
this._exception = exception;
for (ResultDescriptor descriptor in descriptors) {
ResultData data = _getResultData(descriptor);
+ data._invalidate(_cache, new TargetedResult(_target, descriptor));
data.state = CacheState.ERROR;
data.value = descriptor.defaultValue;
}
@@ -396,7 +422,11 @@ class CacheEntry {
}
_validateStateChange(descriptor, state);
if (state == CacheState.INVALID) {
- _resultMap.remove(descriptor);
+ ResultData data = _resultMap[descriptor];
+ if (data != null) {
+ TargetedResult thisResult = new TargetedResult(_target, descriptor);
+ data._invalidate(_cache, thisResult);
+ }
} else {
ResultData data = _getResultData(descriptor);
data.state = state;
@@ -415,9 +445,14 @@ class CacheEntry {
* given [value].
*/
/*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/
- value) {
+ value, List<TargetedResult> dependedOn) {
_validateStateChange(descriptor, CacheState.VALID);
ResultData data = _getResultData(descriptor);
+ {
+ TargetedResult thisResult = new TargetedResult(_target, descriptor);
+ data._invalidate(_cache, thisResult);
+ data._setDependedOnResults(_cache, thisResult, dependedOn);
+ }
data.state = CacheState.VALID;
data.value = value == null ? descriptor.defaultValue : value;
}
@@ -771,6 +806,11 @@ class DefaultRetentionPolicy implements CacheRetentionPolicy {
// can be typed.
class ResultData {
/**
+ * The [ResultDescriptor] this result is for.
+ */
+ final ResultDescriptor descriptor;
+
+ /**
* The state of the cached value.
*/
CacheState state;
@@ -782,12 +822,76 @@ class ResultData {
Object value;
/**
+ * A list of the results on which this result depends.
+ */
+ List<TargetedResult> _dependedOnResults = <TargetedResult>[];
+
+ /**
+ * A list of the results that depend on this result.
+ */
+ List<TargetedResult> _dependentResults = <TargetedResult>[];
+
+ /**
* Initialize a newly created result holder to represent the value of data
* described by the given [descriptor].
*/
- ResultData(ResultDescriptor descriptor) {
+ ResultData(this.descriptor) {
+ state = CacheState.INVALID;
+ value = descriptor.defaultValue;
+ }
+
+ /**
+ * Add the given [result] to the list of dependent results.
+ */
+ void _addDependentResult(TargetedResult result) {
Brian Wilkerson 2015/05/03 15:35:32 I don't understand why we would make these private
scheglov 2015/05/03 20:26:28 No, you're right. I will make these new methods an
+ _dependentResults.add(result);
+ }
+
+ /**
+ * Remove the given [result] from the list of dependent results.
+ */
+ void _removeDependentResult(TargetedResult result) {
+ _dependentResults.remove(result);
+ }
+
+ /**
+ * Invalidate this [ResultData] that corresponds to [thisResult] and
+ * propagate invalidation to the results that depend on this one.
+ */
+ void _invalidate(AnalysisCache cache, TargetedResult thisResult) {
+ // Invalidate this result.
state = CacheState.INVALID;
value = descriptor.defaultValue;
+ // Stop depending on other results.
+ List<TargetedResult> dependedOnResults = _dependedOnResults;
+ _dependedOnResults = <TargetedResult>[];
+ dependedOnResults.forEach((TargetedResult dependedOnResult) {
+ ResultData data = cache._getDataFor(dependedOnResult);
+ data._removeDependentResult(thisResult);
+ });
+ // Invalidate results that depend on this result.
+ List<TargetedResult> dependentResults = _dependentResults;
+ _dependentResults = <TargetedResult>[];
+ dependentResults.forEach((TargetedResult dependentResult) {
+ ResultData data = cache._getDataFor(dependentResult);
+ data._invalidate(cache, dependentResult);
+ });
+ }
+
+ /**
+ * Set the [dependedOn] on which this result depends.
+ */
+ void _setDependedOnResults(AnalysisCache cache, TargetedResult thisResult,
+ List<TargetedResult> dependedOn) {
+ _dependedOnResults.forEach((TargetedResult dependedOnResult) {
+ ResultData data = cache._getDataFor(dependedOnResult);
+ data._removeDependentResult(thisResult);
+ });
+ _dependedOnResults = dependedOn;
+ _dependedOnResults.forEach((TargetedResult dependentResult) {
+ ResultData data = cache._getDataFor(dependentResult);
+ data._addDependentResult(thisResult);
+ });
}
}
@@ -811,6 +915,46 @@ class SdkCachePartition extends CachePartition {
}
/**
+ * A specification of a specific result computed for a specific target.
+ */
+class TargetedResult {
+ /**
+ * An empty list of results.
+ */
+ static final List<TargetedResult> EMPTY_LIST = const <TargetedResult>[];
+
+ /**
+ * The target with which the result is associated.
+ */
+ final AnalysisTarget target;
+
+ /**
+ * The result associated with the target.
+ */
+ final ResultDescriptor result;
+
+ /**
+ * Initialize a new targeted result.
+ */
+ TargetedResult(this.target, this.result);
+
+ @override
+ int get hashCode {
+ return JenkinsSmiHash.combine(target.hashCode, result.hashCode);
+ }
+
+ @override
+ bool operator ==(other) {
+ return other is TargetedResult &&
+ other.target == target &&
+ other.result == result;
+ }
+
+ @override
+ String toString() => '$result for $target';
+}
+
+/**
* A cache partition that contains all targets not contained in other partitions.
*/
class UniversalCachePartition extends CachePartition {
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/context/context.dart » ('j') | pkg/analyzer/test/src/context/abstract_context_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698