| Index: pkg/front_end/lib/src/byte_store/cache.dart
|
| diff --git a/pkg/front_end/lib/src/byte_store/cache.dart b/pkg/front_end/lib/src/byte_store/cache.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..47a32a3d32219a46922240f3833470c64765f602
|
| --- /dev/null
|
| +++ b/pkg/front_end/lib/src/byte_store/cache.dart
|
| @@ -0,0 +1,58 @@
|
| +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
|
| +// 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';
|
| +
|
| +/**
|
| + * LRU cache of objects.
|
| + */
|
| +class Cache<K, V> {
|
| + final int _maxSizeBytes;
|
| + final int Function(V) _meter;
|
| +
|
| + final _map = new LinkedHashMap<K, V>();
|
| + int _currentSizeBytes = 0;
|
| +
|
| + Cache(this._maxSizeBytes, this._meter);
|
| +
|
| + V get(K key, V getNotCached()) {
|
| + V value = _map.remove(key);
|
| + if (value == null) {
|
| + value = getNotCached();
|
| + if (value != null) {
|
| + _map[key] = value;
|
| + _currentSizeBytes += _meter(value);
|
| + _evict();
|
| + }
|
| + } else {
|
| + _map[key] = value;
|
| + }
|
| + return value;
|
| + }
|
| +
|
| + void put(K key, V value) {
|
| + V oldValue = _map[key];
|
| + if (oldValue != null) {
|
| + _currentSizeBytes -= _meter(oldValue);
|
| + }
|
| + _map[key] = value;
|
| + _currentSizeBytes += _meter(value);
|
| + _evict();
|
| + }
|
| +
|
| + void _evict() {
|
| + while (_currentSizeBytes > _maxSizeBytes) {
|
| + if (_map.isEmpty) {
|
| + // Should be impossible, since _currentSizeBytes should always match
|
| + // _map. But recover anyway.
|
| + assert(false);
|
| + _currentSizeBytes = 0;
|
| + break;
|
| + }
|
| + K key = _map.keys.first;
|
| + V value = _map.remove(key);
|
| + _currentSizeBytes -= _meter(value);
|
| + }
|
| + }
|
| +}
|
|
|