| OLD | NEW |
| 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 'dart:collection'; | 5 import 'package:front_end/src/byte_store/cache.dart'; |
| 6 | |
| 7 /** | |
| 8 * In-memory LRU cache for bytes. | |
| 9 */ | |
| 10 class BytesMemoryCache<K> { | |
| 11 final int _maxSizeBytes; | |
| 12 | |
| 13 final _map = new LinkedHashMap<K, List<int>>(); | |
| 14 int _currentSizeBytes = 0; | |
| 15 | |
| 16 BytesMemoryCache(this._maxSizeBytes); | |
| 17 | |
| 18 List<int> get(K key, List<int> getNotCached()) { | |
| 19 List<int> bytes = _map.remove(key); | |
| 20 if (bytes == null) { | |
| 21 bytes = getNotCached(); | |
| 22 if (bytes != null) { | |
| 23 _map[key] = bytes; | |
| 24 _currentSizeBytes += bytes.length; | |
| 25 _evict(); | |
| 26 } | |
| 27 } else { | |
| 28 _map[key] = bytes; | |
| 29 } | |
| 30 return bytes; | |
| 31 } | |
| 32 | |
| 33 void put(K key, List<int> bytes) { | |
| 34 _currentSizeBytes -= _map[key]?.length ?? 0; | |
| 35 _map[key] = bytes; | |
| 36 _currentSizeBytes += bytes.length; | |
| 37 _evict(); | |
| 38 } | |
| 39 | |
| 40 void _evict() { | |
| 41 while (_currentSizeBytes > _maxSizeBytes) { | |
| 42 if (_map.isEmpty) { | |
| 43 // Should be impossible, since _currentSizeBytes should always match | |
| 44 // _map. But recover anyway. | |
| 45 assert(false); | |
| 46 _currentSizeBytes = 0; | |
| 47 break; | |
| 48 } | |
| 49 K key = _map.keys.first; | |
| 50 List<int> bytes = _map.remove(key); | |
| 51 _currentSizeBytes -= bytes.length; | |
| 52 } | |
| 53 } | |
| 54 } | |
| 55 | 6 |
| 56 /** | 7 /** |
| 57 * Store of bytes associated with string keys. | 8 * Store of bytes associated with string keys. |
| 58 * | 9 * |
| 59 * Each key must be not longer than 100 characters and consist of only `[a-z]`, | 10 * Each key must be not longer than 100 characters and consist of only `[a-z]`, |
| 60 * `[0-9]`, `.` and `_` characters. The key cannot be an empty string, the | 11 * `[0-9]`, `.` and `_` characters. The key cannot be an empty string, the |
| 61 * literal `.`, or contain the sequence `..`. | 12 * literal `.`, or contain the sequence `..`. |
| 62 * | 13 * |
| 63 * Note that associations are not guaranteed to be persistent. The value | 14 * Note that associations are not guaranteed to be persistent. The value |
| 64 * associated with a key can change or become `null` at any point in time. | 15 * associated with a key can change or become `null` at any point in time. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 93 void put(String key, List<int> bytes) { | 44 void put(String key, List<int> bytes) { |
| 94 _map[key] = bytes; | 45 _map[key] = bytes; |
| 95 } | 46 } |
| 96 } | 47 } |
| 97 | 48 |
| 98 /** | 49 /** |
| 99 * A wrapper around [ByteStore] which adds an in-memory LRU cache to it. | 50 * A wrapper around [ByteStore] which adds an in-memory LRU cache to it. |
| 100 */ | 51 */ |
| 101 class MemoryCachingByteStore implements ByteStore { | 52 class MemoryCachingByteStore implements ByteStore { |
| 102 final ByteStore _store; | 53 final ByteStore _store; |
| 103 final BytesMemoryCache<String> _cache; | 54 final Cache<String, List<int>> _cache; |
| 104 | 55 |
| 105 MemoryCachingByteStore(this._store, int maxSizeBytes) | 56 MemoryCachingByteStore(this._store, int maxSizeBytes) |
| 106 : _cache = new BytesMemoryCache<String>(maxSizeBytes); | 57 : _cache = new Cache<String, List<int>>(maxSizeBytes, (v) => v.length); |
| 107 | 58 |
| 108 @override | 59 @override |
| 109 List<int> get(String key) { | 60 List<int> get(String key) { |
| 110 return _cache.get(key, () => _store.get(key)); | 61 return _cache.get(key, () => _store.get(key)); |
| 111 } | 62 } |
| 112 | 63 |
| 113 @override | 64 @override |
| 114 void put(String key, List<int> bytes) { | 65 void put(String key, List<int> bytes) { |
| 115 _store.put(key, bytes); | 66 _store.put(key, bytes); |
| 116 _cache.put(key, bytes); | 67 _cache.put(key, bytes); |
| 117 } | 68 } |
| 118 } | 69 } |
| 119 | 70 |
| 120 /** | 71 /** |
| 121 * [ByteStore] which does not store any data. | 72 * [ByteStore] which does not store any data. |
| 122 */ | 73 */ |
| 123 class NullByteStore implements ByteStore { | 74 class NullByteStore implements ByteStore { |
| 124 @override | 75 @override |
| 125 List<int> get(String key) => null; | 76 List<int> get(String key) => null; |
| 126 | 77 |
| 127 @override | 78 @override |
| 128 void put(String key, List<int> bytes) {} | 79 void put(String key, List<int> bytes) {} |
| 129 } | 80 } |
| OLD | NEW |