Skip to content

Commit fdad84f

Browse files
keertipcommit-bot@chromium.org
authored andcommitted
Modify FileResolver / bytestore to keep track of invalidated cache elements.
Change-Id: I60cb1f5f04eb9a1ee34c50157d5ed2da92d408ec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167861 Commit-Queue: Keerti Parthasarathy <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 5a28f14 commit fdad84f

File tree

3 files changed

+70
-21
lines changed

3 files changed

+70
-21
lines changed

pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
import 'package:analyzer/src/dart/analysis/cache.dart';
66
import 'package:collection/collection.dart';
77

8+
class CacheData {
9+
final int id;
10+
final List<int> bytes;
11+
12+
CacheData(this.id, this.bytes);
13+
}
14+
815
/// Store of bytes associated with string keys and a hash.
916
///
1017
/// Each key must be not longer than 100 characters and consist of only `[a-z]`,
@@ -18,39 +25,52 @@ abstract class CiderByteStore {
1825
/// [signature].
1926
///
2027
/// Return `null` if the association does not exist.
21-
List<int> get(String key, List<int> signature);
28+
CacheData get(String key, List<int> signature);
29+
30+
/// Associate the given [bytes] with the [key] and [signature]. Return the
31+
/// [CacheData].
32+
CacheData putGet(String key, List<int> signature, List<int> bytes);
2233

23-
/// Associate the given [bytes] with the [key] and [digest].
24-
void put(String key, List<int> signature, List<int> bytes);
34+
/// Used to decrement reference count for the given ids, if implemented.
35+
void release(Iterable<int> ids);
2536
}
2637

2738
class CiderCachedByteStore implements CiderByteStore {
2839
final Cache<String, CiderCacheEntry> _cache;
40+
int idCounter = 0;
2941

3042
CiderCachedByteStore(int maxCacheSize)
31-
: _cache =
32-
Cache<String, CiderCacheEntry>(maxCacheSize, (v) => v.bytes.length);
43+
: _cache = Cache<String, CiderCacheEntry>(
44+
maxCacheSize, (v) => v.data.bytes.length);
3345

3446
@override
35-
List<int> get(String key, List<int> signature) {
47+
CacheData get(String key, List<int> signature) {
3648
var entry = _cache.get(key, () => null);
3749

3850
if (entry != null &&
3951
const ListEquality<int>().equals(entry.signature, signature)) {
40-
return entry.bytes;
52+
return entry.data;
4153
}
4254
return null;
4355
}
4456

4557
@override
46-
void put(String key, List<int> signature, List<int> bytes) {
47-
_cache.put(key, CiderCacheEntry(signature, bytes));
58+
CacheData putGet(String key, List<int> signature, List<int> bytes) {
59+
idCounter++;
60+
var entry = CiderCacheEntry(signature, CacheData(idCounter, bytes));
61+
_cache.put(key, entry);
62+
return entry.data;
63+
}
64+
65+
@override
66+
void release(Iterable<int> ids) {
67+
// do nothing
4868
}
4969
}
5070

5171
class CiderCacheEntry {
72+
final CacheData data;
5273
final List<int> signature;
53-
final List<int> bytes;
5474

55-
CiderCacheEntry(this.signature, this.bytes);
75+
CiderCacheEntry(this.signature, this.data);
5676
}

pkg/analyzer/lib/src/dart/micro/library_graph.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ class FileState {
9090
UnlinkedUnit2 unlinked2;
9191
LibraryCycle _libraryCycle;
9292

93+
/// id of the cache entry.
94+
int id;
95+
9396
FileState._(
9497
this._fsState,
9598
this.path,
@@ -219,7 +222,8 @@ class FileState {
219222
// Prepare bytes of the unlinked bundle - existing or new.
220223
List<int> bytes;
221224
{
222-
bytes = _fsState._byteStore.get(unlinkedKey, _digest);
225+
var cacheData = _fsState._byteStore.get(unlinkedKey, _digest);
226+
bytes = cacheData?.bytes;
223227

224228
if (bytes == null || bytes.isEmpty) {
225229
var content = performance.run('content', (_) {
@@ -236,14 +240,16 @@ class FileState {
236240
var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
237241
bytes = unlinkedBuilder.toBuffer();
238242
performance.getDataInt('length').add(bytes.length);
239-
_fsState._byteStore.put(unlinkedKey, _digest, bytes);
243+
cacheData = _fsState._byteStore.putGet(unlinkedKey, _digest, bytes);
244+
bytes = cacheData.bytes;
240245
});
241246

242247
performance.run('prefetch', (_) {
243248
unlinked2 = CiderUnlinkedUnit.fromBuffer(bytes).unlinkedUnit;
244249
_prefetchDirectReferences(unlinked2);
245250
});
246251
}
252+
id = cacheData.id;
247253
}
248254

249255
// Read the unlinked bundle.
@@ -645,6 +651,9 @@ class LibraryCycle {
645651
/// The hash of all the paths of the files in this cycle.
646652
String cyclePathsHash;
647653

654+
/// id of the cache entry.
655+
int id;
656+
648657
LibraryCycle();
649658

650659
String get signatureStr {

pkg/analyzer/lib/src/dart/micro/resolve_file.dart

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ class FileResolver {
8383

8484
_LibraryContext libraryContext;
8585

86+
/// List of ids for cache elements that are invalidated. Track elements that
87+
/// are invalidated during [changeFile]. Used in [releaseAndClearRemovedIds] to
88+
/// release the cache items and is then cleared.
89+
final Set<int> removedCacheIds = {};
90+
8691
FileResolver(
8792
PerformanceLog logger,
8893
ResourceProvider resourceProvider,
@@ -132,7 +137,8 @@ class FileResolver {
132137
/// Update the resolver to reflect the fact that the file with the given
133138
/// [path] was changed. We need to make sure that when this file, of any file
134139
/// that directly or indirectly referenced it, is resolved, we used the new
135-
/// state of the file.
140+
/// state of the file. Updates [removedCacheIds] with the ids of the invalidated
141+
/// items, used in [releaseAndClearRemovedIds] to release the cache items.
136142
void changeFile(String path) {
137143
if (fsState == null) {
138144
return;
@@ -149,12 +155,13 @@ class FileResolver {
149155
path: removedFile.path,
150156
uri: removedFile.uri,
151157
);
158+
removedCacheIds.add(removedFile.id);
152159
}
153160

154161
// Remove libraries represented by removed files.
155162
// If we need these libraries later, we will relink and reattach them.
156163
if (libraryContext != null) {
157-
libraryContext.remove(removedFiles);
164+
libraryContext.remove(removedFiles, removedCacheIds);
158165
}
159166
}
160167

@@ -184,7 +191,7 @@ class FileResolver {
184191
var errorsSignature = errorsSignatureBuilder.toByteList();
185192

186193
var errorsKey = file.path + '.errors';
187-
var bytes = byteStore.get(errorsKey, errorsSignature);
194+
var bytes = byteStore.get(errorsKey, errorsSignature)?.bytes;
188195
List<AnalysisError> errors;
189196
if (bytes != null) {
190197
var data = CiderUnitErrors.fromBuffer(bytes);
@@ -204,7 +211,7 @@ class FileResolver {
204211
signature: errorsSignature,
205212
errors: errors.map(ErrorEncoding.encode).toList(),
206213
).toBuffer();
207-
byteStore.put(errorsKey, errorsSignature, bytes);
214+
bytes = byteStore.putGet(errorsKey, errorsSignature, bytes).bytes;
208215
}
209216

210217
return ErrorsResultImpl(
@@ -314,6 +321,12 @@ class FileResolver {
314321
_resetContextObjects();
315322
}
316323

324+
/// Update the cache with list of invalidated ids and clears [removedCacheIds].
325+
void releaseAndClearRemovedIds() {
326+
byteStore.release(removedCacheIds);
327+
removedCacheIds.clear();
328+
}
329+
317330
/// The [completionLine] and [completionColumn] are zero based.
318331
ResolvedUnitResult resolve({
319332
int completionLine,
@@ -680,7 +693,8 @@ class _LibraryContext {
680693
cycle.directDependencies.forEach(loadBundle);
681694

682695
var key = cycle.cyclePathsHash;
683-
var bytes = byteStore.get(key, cycle.signature);
696+
var data = byteStore.get(key, cycle.signature);
697+
var bytes = data?.bytes;
684698

685699
if (bytes == null) {
686700
librariesLinkedTimer.start();
@@ -732,14 +746,16 @@ class _LibraryContext {
732746

733747
bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
734748

735-
byteStore.put(key, cycle.signature, bytes);
749+
data = byteStore.putGet(key, cycle.signature, bytes);
750+
bytes = data.bytes;
736751
performance.getDataInt('bytesPut').add(bytes.length);
737752

738753
librariesLinkedTimer.stop();
739754
} else {
740755
performance.getDataInt('bytesGet').add(bytes.length);
741756
performance.getDataInt('libraryLoadCount').add(cycle.libraries.length);
742757
}
758+
cycle.id = data.id;
743759

744760
var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
745761
inputBundles.add(cBundle.bundle);
@@ -775,14 +791,18 @@ class _LibraryContext {
775791

776792
/// Remove libraries represented by the [removed] files.
777793
/// If we need these libraries later, we will relink and reattach them.
778-
void remove(List<FileState> removed) {
794+
void remove(List<FileState> removed, Set<int> removedIds) {
779795
elementFactory.removeLibraries(
780796
removed.map((e) => e.uriStr).toSet(),
781797
);
782798

783799
var removedSet = removed.toSet();
784800
loadedBundles.removeWhere((cycle) {
785-
return cycle.libraries.any(removedSet.contains);
801+
if (cycle.libraries.any(removedSet.contains)) {
802+
removedIds.add(cycle.id);
803+
return true;
804+
}
805+
return false;
786806
});
787807
}
788808

0 commit comments

Comments
 (0)