mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
When invalidate because of the ERROR state, propagate its exception.
I have to move invalidation implementation into CacheEntry, because we need to set the "exception" field value. Should we also move "setDependedOnResults" and make ResultData a dumb data container? R=brianwilkerson@google.com BUG= Review URL: https://codereview.chromium.org//1126793004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45608 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
965ac274f6
commit
11f96844dc
2 changed files with 76 additions and 86 deletions
|
@ -345,9 +345,7 @@ class CacheEntry {
|
|||
}
|
||||
this._exception = exception;
|
||||
for (ResultDescriptor descriptor in descriptors) {
|
||||
ResultData data = _getResultData(descriptor);
|
||||
TargetedResult thisResult = new TargetedResult(_target, descriptor);
|
||||
data.invalidate(_partition, thisResult, CacheState.ERROR);
|
||||
_invalidate(descriptor, exception);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,8 +364,7 @@ class CacheEntry {
|
|||
if (state == CacheState.INVALID) {
|
||||
ResultData data = _resultMap[descriptor];
|
||||
if (data != null) {
|
||||
TargetedResult thisResult = new TargetedResult(_target, descriptor);
|
||||
data.invalidate(_partition, thisResult, CacheState.INVALID);
|
||||
_invalidate(descriptor, null);
|
||||
}
|
||||
} else {
|
||||
ResultData data = _getResultData(descriptor);
|
||||
|
@ -394,9 +391,9 @@ class CacheEntry {
|
|||
if (_partition != null) {
|
||||
_partition.resultStored(thisResult, value);
|
||||
}
|
||||
_invalidate(descriptor, null);
|
||||
ResultData data = _getResultData(descriptor);
|
||||
data.invalidate(_partition, thisResult, CacheState.INVALID);
|
||||
data.setDependedOnResults(_partition, thisResult, dependedOn);
|
||||
_setDependedOnResults(data, thisResult, dependedOn);
|
||||
data.state = CacheState.VALID;
|
||||
data.value = value == null ? descriptor.defaultValue : value;
|
||||
data.memento = memento;
|
||||
|
@ -422,6 +419,49 @@ class CacheEntry {
|
|||
return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the result represented by the given [descriptor].
|
||||
* Propagate invalidation to other results that depend on it.
|
||||
*/
|
||||
void _invalidate(ResultDescriptor descriptor, CaughtException exception) {
|
||||
ResultData thisData = _getResultData(descriptor);
|
||||
// Invalidate this result.
|
||||
if (exception == null) {
|
||||
thisData.state = CacheState.INVALID;
|
||||
} else {
|
||||
thisData.state = CacheState.ERROR;
|
||||
_exception = exception;
|
||||
}
|
||||
thisData.value = descriptor.defaultValue;
|
||||
// Stop depending on other results.
|
||||
TargetedResult thisResult = new TargetedResult(_target, descriptor);
|
||||
List<TargetedResult> dependedOnResults = thisData.dependedOnResults;
|
||||
thisData.dependedOnResults = <TargetedResult>[];
|
||||
dependedOnResults.forEach((TargetedResult dependedOnResult) {
|
||||
ResultData data = _partition._getDataFor(dependedOnResult);
|
||||
data.dependentResults.remove(thisResult);
|
||||
});
|
||||
// Invalidate results that depend on this result.
|
||||
List<TargetedResult> dependentResults = thisData.dependentResults;
|
||||
thisData.dependentResults = <TargetedResult>[];
|
||||
dependentResults.forEach((TargetedResult dependentResult) {
|
||||
CacheEntry entry = _partition.get(dependentResult.target);
|
||||
entry._invalidate(dependentResult.result, exception);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the [dependedOn] on which this result depends.
|
||||
*/
|
||||
void _setDependedOnResults(ResultData thisData, TargetedResult thisResult,
|
||||
List<TargetedResult> dependedOn) {
|
||||
thisData.dependedOnResults = dependedOn;
|
||||
thisData.dependedOnResults.forEach((TargetedResult dependentResult) {
|
||||
ResultData data = _partition._getDataFor(dependentResult);
|
||||
data.dependentResults.add(thisResult);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the flag with the given [index] to the given [value].
|
||||
*/
|
||||
|
@ -784,13 +824,6 @@ class ResultData {
|
|||
value = descriptor.defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given [result] to the list of dependent results.
|
||||
*/
|
||||
void addDependentResult(TargetedResult result) {
|
||||
dependentResults.add(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush this value.
|
||||
*/
|
||||
|
@ -798,54 +831,6 @@ class ResultData {
|
|||
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(CachePartition partition, TargetedResult thisResult,
|
||||
CacheState newState) {
|
||||
// Invalidate this result.
|
||||
state = newState;
|
||||
value = descriptor.defaultValue;
|
||||
// Stop depending on other results.
|
||||
List<TargetedResult> dependedOnResults = this.dependedOnResults;
|
||||
this.dependedOnResults = <TargetedResult>[];
|
||||
dependedOnResults.forEach((TargetedResult 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 = partition._getDataFor(dependentResult);
|
||||
data.invalidate(partition, dependentResult, newState);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given [result] from the list of dependent results.
|
||||
*/
|
||||
void removeDependentResult(TargetedResult result) {
|
||||
dependentResults.remove(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the [dependedOn] on which this result depends.
|
||||
*/
|
||||
void setDependedOnResults(CachePartition partition, TargetedResult thisResult,
|
||||
List<TargetedResult> dependedOn) {
|
||||
dependedOnResults.forEach((TargetedResult dependedOnResult) {
|
||||
ResultData data = partition._getDataFor(dependedOnResult);
|
||||
data.removeDependentResult(thisResult);
|
||||
});
|
||||
dependedOnResults = dependedOn;
|
||||
dependedOnResults.forEach((TargetedResult dependentResult) {
|
||||
ResultData data = partition._getDataFor(dependentResult);
|
||||
data.addDependentResult(thisResult);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -242,38 +242,43 @@ class CacheEntryTest extends EngineTestCase {
|
|||
}
|
||||
|
||||
test_setErrorState_invalidateDependent() {
|
||||
AnalysisTarget target = new TestSource();
|
||||
CacheEntry entry = new CacheEntry();
|
||||
cache.put(target, entry);
|
||||
AnalysisTarget target1 = new TestSource('/a.dart');
|
||||
AnalysisTarget target2 = new TestSource('/b.dart');
|
||||
CacheEntry entry1 = new CacheEntry();
|
||||
CacheEntry entry2 = new CacheEntry();
|
||||
cache.put(target1, entry1);
|
||||
cache.put(target2, entry2);
|
||||
ResultDescriptor result1 = new ResultDescriptor('result1', -1);
|
||||
ResultDescriptor result2 = new ResultDescriptor('result2', -2);
|
||||
ResultDescriptor result3 = new ResultDescriptor('result3', -3);
|
||||
ResultDescriptor result4 = new ResultDescriptor('result4', -4);
|
||||
// set results, all of them are VALID
|
||||
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST, null);
|
||||
entry.setValue(result2, 222, [new TargetedResult(target, result1)], null);
|
||||
entry.setValue(result3, 333, [new TargetedResult(target, result2)], null);
|
||||
entry.setValue(result4, 444, [], null);
|
||||
expect(entry.getState(result1), CacheState.VALID);
|
||||
expect(entry.getState(result2), CacheState.VALID);
|
||||
expect(entry.getState(result3), CacheState.VALID);
|
||||
expect(entry.getState(result4), CacheState.VALID);
|
||||
expect(entry.getValue(result1), 111);
|
||||
expect(entry.getValue(result2), 222);
|
||||
expect(entry.getValue(result3), 333);
|
||||
expect(entry.getValue(result4), 444);
|
||||
entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST, null);
|
||||
entry2.setValue(result2, 222, [new TargetedResult(target1, result1)], null);
|
||||
entry2.setValue(result3, 333, [new TargetedResult(target2, result2)], null);
|
||||
entry2.setValue(result4, 444, [], null);
|
||||
expect(entry1.getState(result1), CacheState.VALID);
|
||||
expect(entry2.getState(result2), CacheState.VALID);
|
||||
expect(entry2.getState(result3), CacheState.VALID);
|
||||
expect(entry2.getState(result4), CacheState.VALID);
|
||||
expect(entry1.getValue(result1), 111);
|
||||
expect(entry2.getValue(result2), 222);
|
||||
expect(entry2.getValue(result3), 333);
|
||||
expect(entry2.getValue(result4), 444);
|
||||
// set error state
|
||||
CaughtException exception = new CaughtException(null, null);
|
||||
entry.setErrorState(exception, <ResultDescriptor>[result1]);
|
||||
entry1.setErrorState(exception, <ResultDescriptor>[result1]);
|
||||
// result2 and result3 are invalidated, result4 is intact
|
||||
expect(entry.getState(result1), CacheState.ERROR);
|
||||
expect(entry.getState(result2), CacheState.ERROR);
|
||||
expect(entry.getState(result3), CacheState.ERROR);
|
||||
expect(entry.getState(result4), CacheState.VALID);
|
||||
expect(entry.getValue(result1), -1);
|
||||
expect(entry.getValue(result2), -2);
|
||||
expect(entry.getValue(result3), -3);
|
||||
expect(entry.getValue(result4), 444);
|
||||
expect(entry1.getState(result1), CacheState.ERROR);
|
||||
expect(entry2.getState(result2), CacheState.ERROR);
|
||||
expect(entry2.getState(result3), CacheState.ERROR);
|
||||
expect(entry2.getState(result4), CacheState.VALID);
|
||||
expect(entry1.getValue(result1), -1);
|
||||
expect(entry2.getValue(result2), -2);
|
||||
expect(entry2.getValue(result3), -3);
|
||||
expect(entry2.getValue(result4), 444);
|
||||
expect(entry1.exception, exception);
|
||||
expect(entry2.exception, exception);
|
||||
}
|
||||
|
||||
test_setErrorState_noDescriptors() {
|
||||
|
|
Loading…
Reference in a new issue