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

Side by Side Diff: pkg/analyzer/lib/src/summary/incremental_cache.dart

Issue 2064613004: Compact incremental cache when we're done using it. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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/test/src/summary/incremental_cache_test.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'dart:collection';
5 import 'dart:convert'; 6 import 'dart:convert';
6 import 'dart:core' hide Resource; 7 import 'dart:core' hide Resource;
7 8
8 import 'package:analyzer/dart/element/element.dart'; 9 import 'package:analyzer/dart/element/element.dart';
9 import 'package:analyzer/file_system/file_system.dart'; 10 import 'package:analyzer/file_system/file_system.dart';
10 import 'package:analyzer/src/generated/engine.dart'; 11 import 'package:analyzer/src/generated/engine.dart';
11 import 'package:analyzer/src/generated/error.dart'; 12 import 'package:analyzer/src/generated/error.dart';
12 import 'package:analyzer/src/generated/source.dart'; 13 import 'package:analyzer/src/generated/source.dart';
13 import 'package:analyzer/src/summary/format.dart'; 14 import 'package:analyzer/src/summary/format.dart';
14 import 'package:analyzer/src/summary/idl.dart'; 15 import 'package:analyzer/src/summary/idl.dart';
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 return 1; 52 return 1;
52 } 53 }
53 return 0; 54 return 0;
54 } 55 }
55 56
56 /** 57 /**
57 * Storage for cache data. 58 * Storage for cache data.
58 */ 59 */
59 abstract class CacheStorage { 60 abstract class CacheStorage {
60 /** 61 /**
62 * Compact the storage, e.g. remove unused entries.
63 */
64 void compact();
65
66 /**
61 * Return bytes for the given [key], `null` if [key] is not in the storage. 67 * Return bytes for the given [key], `null` if [key] is not in the storage.
62 */ 68 */
63 List<int> get(String key); 69 List<int> get(String key);
64 70
65 /** 71 /**
66 * Associate the [key] with the given [bytes]. 72 * Associate the [key] with the given [bytes].
67 * 73 *
68 * If the [key] was already in the storage, its associated value is changed. 74 * If the [key] was already in the storage, its associated value is changed.
69 * Otherwise the key-value pair is added to the storage. 75 * Otherwise the key-value pair is added to the storage.
70 * 76 *
71 * It is not guaranteed that data will always be accessible using [get], in 77 * It is not guaranteed that data will always be accessible using [get], in
72 * some implementations association may silently fail or become inaccessible 78 * some implementations association may silently fail or become inaccessible
73 * after some time. 79 * after some time.
74 */ 80 */
75 void put(String key, List<int> bytes); 81 void put(String key, List<int> bytes);
76 } 82 }
77 83
78 /** 84 /**
79 * A [Folder] based implementation of [CacheStorage]. 85 * A [Folder] based implementation of [CacheStorage].
80 */ 86 */
81 class FolderCacheStorage implements CacheStorage { 87 class FolderCacheStorage implements CacheStorage {
82 /** 88 /**
89 * The maximum number of entries to keep in the cache.
90 */
91 static const MAX_ENTRIES = 20000;
92
93 /**
83 * The folder to read and write files. 94 * The folder to read and write files.
84 */ 95 */
85 final Folder folder; 96 final Folder folder;
86 97
87 /** 98 /**
88 * To ensure that operations of writing files are atomic we create a temporary 99 * To ensure that operations of writing files are atomic we create a temporary
89 * file with this name in the [folder] and then rename it once we are 100 * file with this name in the [folder] and then rename it once we are
90 * done writing. 101 * done writing.
91 */ 102 */
92 final String tempFileName; 103 final String tempFileName;
93 104
94 FolderCacheStorage(this.folder, this.tempFileName); 105 /**
106 * The set of recently used entries, with the most recently used entries
107 * on the bottom.
108 */
109 final LinkedHashSet<String> _recentEntries = new LinkedHashSet<String>();
110
111 FolderCacheStorage(this.folder, this.tempFileName) {
112 try {
113 File file = folder.getChildAssumingFile('.entries');
114 if (file.exists) {
115 String entriesString = file.readAsStringSync();
116 List<String> entriesLists = entriesString.split('\n');
117 _recentEntries.addAll(entriesLists);
118 }
119 } catch (_) {}
120 }
121
122 @override
123 void compact() {
124 while (_recentEntries.length > MAX_ENTRIES) {
125 String key = _recentEntries.first;
126 _recentEntries.remove(key);
127 try {
128 folder.getChildAssumingFile(key).delete();
129 } catch (_) {}
130 }
131 try {
132 List<int> bytes = UTF8.encode(_recentEntries.join('\n'));
133 folder.getChildAssumingFile('.entries').writeAsBytesSync(bytes);
134 } catch (_) {}
135 }
95 136
96 @override 137 @override
97 List<int> get(String key) { 138 List<int> get(String key) {
98 Resource file = folder.getChild(key); 139 Resource file = folder.getChild(key);
99 if (file is File) { 140 if (file is File) {
100 try { 141 try {
101 return file.readAsBytesSync(); 142 List<int> bytes = file.readAsBytesSync();
143 _accessedKey(key);
144 return bytes;
102 } on FileSystemException {} 145 } on FileSystemException {}
103 } 146 }
104 return null; 147 return null;
105 } 148 }
106 149
107 @override 150 @override
108 void put(String key, List<int> bytes) { 151 void put(String key, List<int> bytes) {
109 String absPath = folder.getChild(key).path; 152 String absPath = folder.getChild(key).path;
110 File tempFile = folder.getChild(tempFileName); 153 File tempFile = folder.getChild(tempFileName);
111 tempFile.writeAsBytesSync(bytes); 154 tempFile.writeAsBytesSync(bytes);
112 try { 155 try {
113 tempFile.renameSync(absPath); 156 tempFile.renameSync(absPath);
157 _accessedKey(key);
114 } catch (e) {} 158 } catch (e) {}
115 } 159 }
160
161 /**
162 * The given [key] was accessed, update recently used entries.
163 */
164 void _accessedKey(String key) {
165 _recentEntries.remove(key);
166 _recentEntries.add(key);
167 }
116 } 168 }
117 169
118 /** 170 /**
119 * Cache of information to support incremental analysis. 171 * Cache of information to support incremental analysis.
120 * 172 *
121 * Note that currently this class is not intended for interactive use. 173 * Note that currently this class is not intended for interactive use.
122 */ 174 */
123 class IncrementalCache { 175 class IncrementalCache {
124 /** 176 /**
125 * The storage for the cache data. 177 * The storage for the cache data.
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 */ 646 */
595 final String id; 647 final String id;
596 648
597 /** 649 /**
598 * The payload bundle. 650 * The payload bundle.
599 */ 651 */
600 final PackageBundle bundle; 652 final PackageBundle bundle;
601 653
602 LibraryBundleWithId(this.source, this.id, this.bundle); 654 LibraryBundleWithId(this.source, this.id, this.bundle);
603 } 655 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/summary/incremental_cache_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698