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

Side by Side Diff: pkg/analyzer/lib/src/context/cache.dart

Issue 1350423002: Partially fix the cache invalidation problem during incremental resolution. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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 unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/incremental_resolver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/incremental_resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698