Chromium Code Reviews| Index: pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart |
| diff --git a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart |
| index 49e668fe08f769ff796c77547e3b546830684fa9..8bd22a55e82c278b6ddd5a2d81e4fff1cfbe5907 100644 |
| --- a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart |
| +++ b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart |
| @@ -2,24 +2,41 @@ |
| // 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 'package:analyzer/file_system/file_system.dart'; |
| import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| /** |
| * [ByteStore] that stores values as [File]s. |
| - * |
| - * TODO(scheglov) Add some eviction policies. |
| */ |
| class FileByteStore implements ByteStore { |
| - final Folder folder; |
| + final Folder _folder; |
| + final String _tempName; |
| + final int _maxSizeBytes; |
| + |
| + final LinkedHashMap<File, int> _files = new LinkedHashMap<File, int>(); |
| + int _currentSizeBytes = 0; |
| - FileByteStore(this.folder); |
| + FileByteStore(this._folder, this._tempName, this._maxSizeBytes) { |
| + for (Resource file in _folder.getChildren()) { |
| + if (file is File) { |
| + int length = file.lengthSync; |
| + _files[file] = length; |
| + _currentSizeBytes += length; |
| + } |
| + } |
| + } |
| @override |
| List<int> get(String key) { |
| try { |
| - File file = folder.getChildAssumingFile(key); |
| - return file.readAsBytesSync(); |
| + File file = _folder.getChildAssumingFile(key); |
| + List<int> bytes = file.readAsBytesSync(); |
| + // Update the file position. |
| + _files.remove(file); |
| + _files[file] = bytes.length; |
| + return bytes; |
| } catch (_) { |
| return null; |
| } |
| @@ -28,8 +45,31 @@ class FileByteStore implements ByteStore { |
| @override |
| void put(String key, List<int> bytes) { |
| try { |
| - File file = folder.getChildAssumingFile(key); |
| - file.writeAsBytesSync(bytes); |
| + File tempFile = _folder.getChildAssumingFile(_tempName); |
| + tempFile.writeAsBytesSync(bytes); |
| + File file = _folder.getChildAssumingFile(key); |
| + tempFile.renameSync(file.path); |
| + // Update the size. |
| + _currentSizeBytes -= _files[key] ?? 0; |
| + _files[file] = bytes.length; |
| + _currentSizeBytes += bytes.length; |
| + _evict(); |
| } catch (_) {} |
| } |
| + |
| + void _evict() { |
| + while (_currentSizeBytes > _maxSizeBytes) { |
| + if (_files.isEmpty) { |
| + break; |
| + } |
| + File file = _files.keys.first; |
| + // Update the size. |
| + int size = _files.remove(file); |
| + _currentSizeBytes -= size; |
| + // Delete the file. |
| + try { |
| + file.delete(); |
|
Brian Wilkerson
2016/11/10 22:12:04
Do we want to decrease the size if we can't actual
|
| + } on FileSystemException {} |
| + } |
| + } |
| } |