Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.context.cache; | 5 library analyzer.src.context.cache; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/engine.dart' | 10 import 'package:analyzer/src/generated/engine.dart' |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 */ | 245 */ |
| 246 class CacheEntry { | 246 class CacheEntry { |
| 247 /** | 247 /** |
| 248 * The index of the flag indicating whether the source was explicitly added to | 248 * The index of the flag indicating whether the source was explicitly added to |
| 249 * the context or whether the source was implicitly added because it was | 249 * the context or whether the source was implicitly added because it was |
| 250 * referenced by another source. | 250 * referenced by another source. |
| 251 */ | 251 */ |
| 252 static int _EXPLICITLY_ADDED_FLAG = 0; | 252 static int _EXPLICITLY_ADDED_FLAG = 0; |
| 253 | 253 |
| 254 /** | 254 /** |
| 255 * The next invalidation process identifier. | |
| 256 */ | |
| 257 static int nextInvalidateId = 0; | |
| 258 | |
| 259 /** | |
| 255 * The target this entry is about. | 260 * The target this entry is about. |
| 256 */ | 261 */ |
| 257 final AnalysisTarget target; | 262 final AnalysisTarget target; |
| 258 | 263 |
| 259 /** | 264 /** |
| 260 * The partition that is responsible for this entry. | 265 * The partition that is responsible for this entry. |
| 261 */ | 266 */ |
| 262 CachePartition _partition; | 267 CachePartition _partition; |
| 263 | 268 |
| 264 /** | 269 /** |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 433 if (state == CacheState.ERROR) { | 438 if (state == CacheState.ERROR) { |
| 434 throw new ArgumentError('use setErrorState() to set the state to ERROR'); | 439 throw new ArgumentError('use setErrorState() to set the state to ERROR'); |
| 435 } | 440 } |
| 436 if (state == CacheState.VALID) { | 441 if (state == CacheState.VALID) { |
| 437 throw new ArgumentError('use setValue() to set the state to VALID'); | 442 throw new ArgumentError('use setValue() to set the state to VALID'); |
| 438 } | 443 } |
| 439 _validateStateChange(descriptor, state); | 444 _validateStateChange(descriptor, state); |
| 440 if (state == CacheState.INVALID) { | 445 if (state == CacheState.INVALID) { |
| 441 ResultData data = _resultMap[descriptor]; | 446 ResultData data = _resultMap[descriptor]; |
| 442 if (data != null) { | 447 if (data != null) { |
| 443 _invalidate(descriptor, delta); | 448 _invalidate(nextInvalidateId++, descriptor, delta, 0); |
| 444 } | 449 } |
| 445 } else { | 450 } else { |
| 446 ResultData data = getResultData(descriptor); | 451 ResultData data = getResultData(descriptor); |
| 447 data.state = state; | 452 data.state = state; |
| 448 if (state != CacheState.IN_PROCESS) { | 453 if (state != CacheState.IN_PROCESS) { |
| 449 // | 454 // |
| 450 // If the state is in-process, we can leave the current value in the | 455 // If the state is in-process, we can leave the current value in the |
| 451 // cache for any 'get' methods to access. | 456 // cache for any 'get' methods to access. |
| 452 // | 457 // |
| 453 data.value = descriptor.defaultValue; | 458 data.value = descriptor.defaultValue; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 483 data.state = CacheState.VALID; | 488 data.state = CacheState.VALID; |
| 484 data.value = value == null ? descriptor.defaultValue : value; | 489 data.value = value == null ? descriptor.defaultValue : value; |
| 485 } | 490 } |
| 486 | 491 |
| 487 /** | 492 /** |
| 488 * Set the value of the result represented by the given [descriptor] to the | 493 * Set the value of the result represented by the given [descriptor] to the |
| 489 * given [value], keep its dependency, invalidate all the dependent result. | 494 * given [value], keep its dependency, invalidate all the dependent result. |
| 490 */ | 495 */ |
| 491 void setValueIncremental(ResultDescriptor descriptor, dynamic value) { | 496 void setValueIncremental(ResultDescriptor descriptor, dynamic value) { |
| 492 ResultData data = getResultData(descriptor); | 497 ResultData data = getResultData(descriptor); |
| 493 _invalidateDependentResults(data, null); | 498 _invalidateDependentResults(null, data, null, 0); |
| 494 data.state = CacheState.VALID; | 499 data.state = CacheState.VALID; |
| 495 data.value = value; | 500 data.value = value; |
| 496 } | 501 } |
| 497 | 502 |
| 498 @override | 503 @override |
| 499 String toString() { | 504 String toString() { |
| 500 StringBuffer buffer = new StringBuffer(); | 505 StringBuffer buffer = new StringBuffer(); |
| 501 _writeOn(buffer); | 506 _writeOn(buffer); |
| 502 return buffer.toString(); | 507 return buffer.toString(); |
| 503 } | 508 } |
| 504 | 509 |
| 505 /** | 510 /** |
| 506 * Return the value of the flag with the given [index]. | 511 * Return the value of the flag with the given [index]. |
| 507 */ | 512 */ |
| 508 bool _getFlag(int index) => BooleanArray.get(_flags, index); | 513 bool _getFlag(int index) => BooleanArray.get(_flags, index); |
| 509 | 514 |
| 510 /** | 515 /** |
| 511 * Invalidate the result represented by the given [descriptor] and propagate | 516 * Invalidate the result represented by the given [descriptor] and propagate |
| 512 * invalidation to other results that depend on it. | 517 * invalidation to other results that depend on it. |
| 513 */ | 518 */ |
| 514 void _invalidate(ResultDescriptor descriptor, Delta delta) { | 519 void _invalidate( |
| 520 int id, ResultDescriptor descriptor, Delta delta, int level) { | |
| 521 ResultData thisData = _resultMap[descriptor]; | |
| 522 if (thisData == null) { | |
| 523 return; | |
| 524 } | |
| 525 // Stop if already validated. | |
| 526 if (delta != null) { | |
| 527 if (thisData.invalidateId == id) { | |
| 528 return; | |
| 529 } | |
| 530 thisData.invalidateId = id; | |
| 531 } | |
| 532 // Ask the delta to validate. | |
| 515 DeltaResult deltaResult = null; | 533 DeltaResult deltaResult = null; |
| 516 if (delta != null) { | 534 if (delta != null) { |
| 517 deltaResult = delta.validate(_partition.context, target, descriptor); | 535 deltaResult = delta.validate(_partition.context, target, descriptor); |
| 518 if (deltaResult == DeltaResult.STOP) { | 536 if (deltaResult == DeltaResult.STOP) { |
| 519 // print('not-invalidate $descriptor for $target'); | |
| 520 return; | 537 return; |
| 521 } | 538 } |
| 522 } | 539 } |
| 523 // print('invalidate $descriptor for $target'); | |
| 524 ResultData thisData; | |
| 525 if (deltaResult == null || deltaResult == DeltaResult.INVALIDATE) { | 540 if (deltaResult == null || deltaResult == DeltaResult.INVALIDATE) { |
| 526 thisData = _resultMap.remove(descriptor); | 541 _resultMap.remove(descriptor); |
| 527 } | 542 // { |
|
Brian Wilkerson
2015/09/18 18:37:42
If you didn't intend to leave this debug code, ple
| |
| 528 if (deltaResult == DeltaResult.KEEP_CONTINUE) { | 543 // String indent = ' ' * level; |
| 529 thisData = _resultMap[descriptor]; | 544 // print('[$id]$indent invalidate $descriptor for $target'); |
| 530 } | 545 // } |
| 531 if (thisData == null) { | |
| 532 return; | |
| 533 } | 546 } |
| 534 // Stop depending on other results. | 547 // Stop depending on other results. |
| 535 TargetedResult thisResult = new TargetedResult(target, descriptor); | 548 TargetedResult thisResult = new TargetedResult(target, descriptor); |
| 536 for (TargetedResult dependedOnResult in thisData.dependedOnResults) { | 549 for (TargetedResult dependedOnResult in thisData.dependedOnResults) { |
| 537 ResultData data = _partition._getDataFor(dependedOnResult); | 550 ResultData data = _partition._getDataFor(dependedOnResult); |
| 538 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) { | 551 if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) { |
| 539 data.dependentResults.remove(thisResult); | 552 data.dependentResults.remove(thisResult); |
| 540 } | 553 } |
| 541 } | 554 } |
| 542 // Invalidate results that depend on this result. | 555 // Invalidate results that depend on this result. |
| 543 _invalidateDependentResults(thisData, delta); | 556 _invalidateDependentResults(id, thisData, delta, level + 1); |
| 544 // If empty, remove the entry altogether. | 557 // If empty, remove the entry altogether. |
| 545 if (_resultMap.isEmpty) { | 558 if (_resultMap.isEmpty) { |
| 546 _partition._targetMap.remove(target); | 559 _partition._targetMap.remove(target); |
| 547 _partition._removeIfSource(target); | 560 _partition._removeIfSource(target); |
| 548 } | 561 } |
| 549 // Notify controller. | 562 // Notify controller. |
| 550 _partition.onResultInvalidated | 563 _partition.onResultInvalidated |
| 551 .add(new InvalidatedResult(this, descriptor, thisData.value)); | 564 .add(new InvalidatedResult(this, descriptor, thisData.value)); |
| 552 } | 565 } |
| 553 | 566 |
| 554 /** | 567 /** |
| 555 * Invalidates all the results of this entry, with propagation. | 568 * Invalidates all the results of this entry, with propagation. |
| 556 */ | 569 */ |
| 557 void _invalidateAll() { | 570 void _invalidateAll() { |
| 558 List<ResultDescriptor> results = _resultMap.keys.toList(); | 571 List<ResultDescriptor> results = _resultMap.keys.toList(); |
| 559 for (ResultDescriptor result in results) { | 572 for (ResultDescriptor result in results) { |
| 560 _invalidate(result, null); | 573 _invalidate(null, result, null, 0); |
| 561 } | 574 } |
| 562 } | 575 } |
| 563 | 576 |
| 564 /** | 577 /** |
| 565 * Invalidate results that depend on [thisData]. | 578 * Invalidate results that depend on [thisData]. |
| 566 */ | 579 */ |
| 567 void _invalidateDependentResults(ResultData thisData, Delta delta) { | 580 void _invalidateDependentResults( |
| 581 int id, ResultData thisData, Delta delta, int level) { | |
| 568 List<TargetedResult> dependentResults = thisData.dependentResults.toList(); | 582 List<TargetedResult> dependentResults = thisData.dependentResults.toList(); |
| 569 for (TargetedResult dependentResult in dependentResults) { | 583 for (TargetedResult dependentResult in dependentResults) { |
| 570 CacheEntry entry = _partition.get(dependentResult.target); | 584 CacheEntry entry = _partition.get(dependentResult.target); |
| 571 if (entry != null) { | 585 if (entry != null) { |
| 572 entry._invalidate(dependentResult.result, delta); | 586 entry._invalidate(id, dependentResult.result, delta, level); |
| 573 } | 587 } |
| 574 } | 588 } |
| 575 } | 589 } |
| 576 | 590 |
| 577 /** | 591 /** |
| 578 * Set the [dependedOn] on which this result depends. | 592 * Set the [dependedOn] on which this result depends. |
| 579 */ | 593 */ |
| 580 void _setDependedOnResults(ResultData thisData, TargetedResult thisResult, | 594 void _setDependedOnResults(ResultData thisData, TargetedResult thisResult, |
| 581 List<TargetedResult> dependedOn) { | 595 List<TargetedResult> dependedOn) { |
| 582 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { | 596 thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) { |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 */ | 1107 */ |
| 1094 CacheState state; | 1108 CacheState state; |
| 1095 | 1109 |
| 1096 /** | 1110 /** |
| 1097 * The value being cached, or the default value for the result if there is no | 1111 * The value being cached, or the default value for the result if there is no |
| 1098 * value (for example, when the [state] is [CacheState.INVALID]). | 1112 * value (for example, when the [state] is [CacheState.INVALID]). |
| 1099 */ | 1113 */ |
| 1100 Object value; | 1114 Object value; |
| 1101 | 1115 |
| 1102 /** | 1116 /** |
| 1117 * The identifier of the invalidation process that most recently checked | |
| 1118 * this value. If it is the same as the current invalidation identifier, | |
| 1119 * then there is no reason to check it (and its subtree again). | |
| 1120 */ | |
| 1121 int invalidateId = -1; | |
| 1122 | |
| 1123 /** | |
| 1103 * A list of the results on which this result depends. | 1124 * A list of the results on which this result depends. |
| 1104 */ | 1125 */ |
| 1105 List<TargetedResult> dependedOnResults = <TargetedResult>[]; | 1126 List<TargetedResult> dependedOnResults = <TargetedResult>[]; |
| 1106 | 1127 |
| 1107 /** | 1128 /** |
| 1108 * A list of the results that depend on this result. | 1129 * A list of the results that depend on this result. |
| 1109 */ | 1130 */ |
| 1110 Set<TargetedResult> dependentResults = new Set<TargetedResult>(); | 1131 Set<TargetedResult> dependentResults = new Set<TargetedResult>(); |
| 1111 | 1132 |
| 1112 /** | 1133 /** |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1173 void resultAccessed(TargetedResult result) {} | 1194 void resultAccessed(TargetedResult result) {} |
| 1174 | 1195 |
| 1175 @override | 1196 @override |
| 1176 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { | 1197 List<TargetedResult> resultStored(TargetedResult newResult, newValue) { |
| 1177 return TargetedResult.EMPTY_LIST; | 1198 return TargetedResult.EMPTY_LIST; |
| 1178 } | 1199 } |
| 1179 | 1200 |
| 1180 @override | 1201 @override |
| 1181 void targetRemoved(AnalysisTarget target) {} | 1202 void targetRemoved(AnalysisTarget target) {} |
| 1182 } | 1203 } |
| OLD | NEW |