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

Side by Side Diff: pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart

Issue 2492933002: Evict from FileByteStore by the total cache size in bytes. (Closed)
Patch Set: Clean up cache in a separate isolate. Created 4 years, 1 month 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 | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | no next file » | 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) 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 import 'package:analyzer/file_system/file_system.dart'; 5 import 'dart:async';
6 import 'dart:io';
7 import 'dart:isolate';
8
6 import 'package:analyzer/src/dart/analysis/byte_store.dart'; 9 import 'package:analyzer/src/dart/analysis/byte_store.dart';
10 import 'package:path/path.dart';
7 11
8 /** 12 /**
9 * [ByteStore] that stores values as [File]s. 13 * [ByteStore] that stores values as files.
10 *
11 * TODO(scheglov) Add some eviction policies.
12 */ 14 */
13 class FileByteStore implements ByteStore { 15 class FileByteStore implements ByteStore {
14 final Folder folder; 16 static bool _evictSendPortShouldBePrepared = true;
17 static SendPort _evictSendPort;
15 18
16 FileByteStore(this.folder); 19 final String _cachePath;
20 final String _tempName = 'temp_${pid}';
21 final int _maxSizeBytes;
22
23 int _currentSizeBytes = 0;
Paul Berry 2016/11/13 15:18:17 Rename this to something like "_bytesWrittenSinceC
scheglov 2016/11/14 16:51:47 Done.
24 bool _evictionIsolateIsRunning = false;
25
26 FileByteStore(this._cachePath, this._maxSizeBytes) {
27 _requestCacheCleanUp();
28 }
17 29
18 @override 30 @override
19 List<int> get(String key) { 31 List<int> get(String key) {
20 try { 32 try {
21 File file = folder.getChildAssumingFile(key); 33 return _getFileForKey(key).readAsBytesSync();
22 return file.readAsBytesSync();
23 } catch (_) { 34 } catch (_) {
24 return null; 35 return null;
25 } 36 }
26 } 37 }
27 38
28 @override 39 @override
29 void put(String key, List<int> bytes) { 40 void put(String key, List<int> bytes) {
30 try { 41 try {
31 File file = folder.getChildAssumingFile(key); 42 File tempFile = _getFileForKey(_tempName);
32 file.writeAsBytesSync(bytes); 43 tempFile.writeAsBytesSync(bytes);
44 File file = _getFileForKey(key);
45 tempFile.renameSync(file.path);
46 // Update the current size.
47 _currentSizeBytes += bytes.length;
48 if (_currentSizeBytes > _maxSizeBytes ~/ 8) {
49 _requestCacheCleanUp();
50 }
33 } catch (_) {} 51 } catch (_) {}
34 } 52 }
53
54 File _getFileForKey(String key) {
55 return new File(join(_cachePath, key));
56 }
57
58 /**
59 * If the cache clean up process has not been requested yet, request it.
60 */
61 Future<Null> _requestCacheCleanUp() async {
62 if (_evictSendPortShouldBePrepared) {
63 _evictSendPortShouldBePrepared = false;
64 ReceivePort response = new ReceivePort();
65 await Isolate.spawn(_cacheCleanUpFunction, response.sendPort);
66 _evictSendPort = await response.first as SendPort;
67 } else {
68 while (_evictSendPort == null) {
69 await new Future.delayed(new Duration(milliseconds: 100), () {});
70 }
71 }
72
73 if (!_evictionIsolateIsRunning) {
74 _evictionIsolateIsRunning = true;
75 try {
76 ReceivePort response = new ReceivePort();
77 _evictSendPort.send([_cachePath, _maxSizeBytes, response.sendPort]);
78 await response.first;
79 } finally {
80 _evictionIsolateIsRunning = false;
81 _currentSizeBytes = 0;
82 }
83 }
84 }
85
86 /**
87 * This function is stated in a new isolate, receives cache clean up requests
Paul Berry 2016/11/13 15:18:17 s/stated/started/
scheglov 2016/11/14 16:51:47 Done.
88 * and
89 */
90 static void _cacheCleanUpFunction(SendPort initialReplyTo) {
91 ReceivePort port = new ReceivePort();
92 initialReplyTo.send(port.sendPort);
93 port.listen((args) async {
94 if (args is List &&
95 args.length == 3 &&
96 args[0] is String &&
97 args[1] is int &&
98 args[2] is SendPort) {
Paul Berry 2016/11/13 15:18:17 It seems weird to send a list of objects to the is
scheglov 2016/11/14 16:51:47 Unfortunately this does not work. SendPort.send s
Paul Berry 2016/11/14 21:19:28 +rmacnak, is this due to a bug in the VM?
99 String cachePath = args[0] as String;
100 int maxSizeBytes = args[1] as int;
101 await _evictFromFolder(cachePath, maxSizeBytes);
102 // Let that client know that we're done.
103 SendPort replyTo = args[2] as SendPort;
104 replyTo.send(true);
105 }
106 });
107 }
108
109 static Future<Null> _evictFromFolder(
110 String cachePath, int maxSizeBytes) async {
111 // Prepare the list of files and their statistics.
112 List<File> files = <File>[];
113 Map<File, FileStat> fileStatMap = {};
114 int currentSizeBytes = 0;
115 List<FileSystemEntity> resources = new Directory(cachePath).listSync();
116 for (FileSystemEntity resource in resources) {
117 if (resource is File) {
118 try {
119 FileStat fileStat = await resource.stat();
120 files.add(resource);
121 fileStatMap[resource] = fileStat;
122 currentSizeBytes += fileStat.size;
123 } catch (_) {}
124 }
125 }
126 files.sort((a, b) {
127 return fileStatMap[a].accessed.millisecondsSinceEpoch -
128 fileStatMap[b].accessed.millisecondsSinceEpoch;
129 });
130
131 // Delete files until the current size is less than the max.
132 for (File file in files) {
133 if (currentSizeBytes < maxSizeBytes) {
134 break;
135 }
136 try {
137 await file.delete();
138 } catch (_) {}
139 currentSizeBytes -= fileStatMap[file].size;
140 }
141 }
35 } 142 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698