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 |