Compact incremental cache when we're done using it.

R=brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org/2064613004 .
This commit is contained in:
Konstantin Shcheglov 2016-06-13 13:25:03 -07:00
parent c0eb4d9dc0
commit e2cb8df046
3 changed files with 62 additions and 4 deletions

View file

@ -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;
@ -57,6 +58,11 @@ int comparePaths(String a, String b) {
* Storage for cache data.
*/
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.
*/
@ -79,6 +85,11 @@ abstract class CacheStorage {
* A [Folder] based implementation of [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.
*/
@ -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);
}
}
/**

View file

@ -282,6 +282,9 @@ part 'foo.dart';
class _TestCacheStorage implements CacheStorage {
final Map<String, List<int>> map = <String, List<int>>{};
@override
void compact() {}
@override
List<int> get(String key) {
return map[key];

View file

@ -48,7 +48,7 @@ IncrementalAnalysisSession configureIncrementalAnalysis(
context.resultProvider = new _CacheBasedResultProvider(context, cache);
// Listen for new libraries to put into the cache.
_IncrementalAnalysisSession session =
new _IncrementalAnalysisSession(options, context, cache);
new _IncrementalAnalysisSession(options, storage, context, cache);
context
.onResultChanged(LIBRARY_ELEMENT1)
.listen((ResultChangedEvent event) {
@ -172,13 +172,14 @@ class _CacheBasedResultProvider extends ResynthesizerResultProvider {
class _IncrementalAnalysisSession implements IncrementalAnalysisSession {
final CommandLineOptions commandLineOptions;
final CacheStorage cacheStorage;
final AnalysisContext context;
final IncrementalCache cache;
final Set<Source> newLibrarySources = new Set<Source>();
_IncrementalAnalysisSession(
this.commandLineOptions, this.context, this.cache);
this.commandLineOptions, this.cacheStorage, this.context, this.cache);
@override
void finish() {
@ -189,6 +190,8 @@ class _IncrementalAnalysisSession implements IncrementalAnalysisSession {
}
_putLibrary(librarySource);
}
// Compact the cache.
cacheStorage.compact();
}
@override