| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |