| Index: pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| diff --git a/pkg/analyzer/lib/src/summary/incremental_cache.dart b/pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| index 184e43c8d1ba26449f8c0ef228e847af62ec36d7..6370234d5bc5eebf2b84dc6bc486cae503a45b27 100644
|
| --- a/pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| +++ b/pkg/analyzer/lib/src/summary/incremental_cache.dart
|
| @@ -2,6 +2,7 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| +import 'dart:collection';
|
| import 'dart:convert';
|
| import 'dart:core' hide Resource;
|
|
|
| @@ -58,6 +59,11 @@ int comparePaths(String a, String b) {
|
| */
|
| abstract class CacheStorage {
|
| /**
|
| + * Compact the storage, e.g. remove unused entries.
|
| + */
|
| + void compact();
|
| +
|
| + /**
|
| * Return bytes for the given [key], `null` if [key] is not in the storage.
|
| */
|
| List<int> get(String key);
|
| @@ -80,6 +86,11 @@ abstract class CacheStorage {
|
| */
|
| class FolderCacheStorage implements CacheStorage {
|
| /**
|
| + * The maximum number of entries to keep in the cache.
|
| + */
|
| + static const MAX_ENTRIES = 20000;
|
| +
|
| + /**
|
| * The folder to read and write files.
|
| */
|
| final Folder folder;
|
| @@ -91,14 +102,46 @@ class FolderCacheStorage implements CacheStorage {
|
| */
|
| final String tempFileName;
|
|
|
| - FolderCacheStorage(this.folder, this.tempFileName);
|
| + /**
|
| + * The set of recently used entries, with the most recently used entries
|
| + * on the bottom.
|
| + */
|
| + final LinkedHashSet<String> _recentEntries = new LinkedHashSet<String>();
|
| +
|
| + FolderCacheStorage(this.folder, this.tempFileName) {
|
| + try {
|
| + File file = folder.getChildAssumingFile('.entries');
|
| + if (file.exists) {
|
| + String entriesString = file.readAsStringSync();
|
| + List<String> entriesLists = entriesString.split('\n');
|
| + _recentEntries.addAll(entriesLists);
|
| + }
|
| + } catch (_) {}
|
| + }
|
| +
|
| + @override
|
| + void compact() {
|
| + while (_recentEntries.length > MAX_ENTRIES) {
|
| + String key = _recentEntries.first;
|
| + _recentEntries.remove(key);
|
| + try {
|
| + folder.getChildAssumingFile(key).delete();
|
| + } catch (_) {}
|
| + }
|
| + try {
|
| + List<int> bytes = UTF8.encode(_recentEntries.join('\n'));
|
| + folder.getChildAssumingFile('.entries').writeAsBytesSync(bytes);
|
| + } catch (_) {}
|
| + }
|
|
|
| @override
|
| List<int> get(String key) {
|
| Resource file = folder.getChild(key);
|
| if (file is File) {
|
| try {
|
| - return file.readAsBytesSync();
|
| + List<int> bytes = file.readAsBytesSync();
|
| + _accessedKey(key);
|
| + return bytes;
|
| } on FileSystemException {}
|
| }
|
| return null;
|
| @@ -111,8 +154,17 @@ class FolderCacheStorage implements CacheStorage {
|
| tempFile.writeAsBytesSync(bytes);
|
| try {
|
| tempFile.renameSync(absPath);
|
| + _accessedKey(key);
|
| } catch (e) {}
|
| }
|
| +
|
| + /**
|
| + * The given [key] was accessed, update recently used entries.
|
| + */
|
| + void _accessedKey(String key) {
|
| + _recentEntries.remove(key);
|
| + _recentEntries.add(key);
|
| + }
|
| }
|
|
|
| /**
|
|
|