blob: 92cb27ca73575efd5eb4fd730190bd9e8ea059a3 [file] [log] [blame]
// Copyright (c) 2020, 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:typed_data';
import 'package:meta/meta.dart';
class CacheData {
final int id;
final Uint8List bytes;
CacheData(this.id, this.bytes);
}
/// Store of bytes associated with string keys and a hash.
///
/// Each key must be not longer than 100 characters and consist of only `[a-z]`,
/// `[0-9]`, `.` and `_` characters. The key cannot be an empty string, the
/// literal `.`, or contain the sequence `..`.
///
/// Note that associations are not guaranteed to be persistent. The value
/// associated with a key can change or become `null` at any point in time.
abstract class CiderByteStore {
/// Return the bytes associated with the [key], and increment the reference
/// count.
///
/// Return `null` if the association does not exist.
Uint8List? get2(String key);
/// Associate [bytes] with [key].
/// Return an internalized version of [bytes], the reference count is `1`.
///
/// This method will throw an exception if there is already an association
/// for the [key]. The client should either use [get2] to access data,
/// or first [release2] it.
Uint8List putGet2(String key, Uint8List bytes);
/// Decrement the reference count for every key in [keys].
void release2(Iterable<String> keys);
}
class CiderByteStoreTestView {
int length = 0;
}
/// [CiderByteStore] that keeps all data in local memory.
class MemoryCiderByteStore implements CiderByteStore {
@visibleForTesting
final Map<String, MemoryCiderByteStoreEntry> map = {};
/// This field gets value only during testing.
CiderByteStoreTestView? testView;
@override
Uint8List? get2(String key) {
final entry = map[key];
if (entry == null) {
return null;
}
entry.refCount++;
return entry.bytes;
}
@override
Uint8List putGet2(String key, Uint8List bytes) {
if (map.containsKey(key)) {
throw StateError('Overwriting is not allowed: $key');
}
testView?.length++;
map[key] = MemoryCiderByteStoreEntry._(bytes);
return bytes;
}
@override
void release2(Iterable<String> keys) {
for (final key in keys) {
final entry = map[key];
if (entry != null) {
entry.refCount--;
if (entry.refCount == 0) {
map.remove(key);
}
}
}
}
}
@visibleForTesting
class MemoryCiderByteStoreEntry {
final Uint8List bytes;
int refCount = 1;
MemoryCiderByteStoreEntry._(this.bytes);
@override
String toString() {
return '(length: ${bytes.length}, refCount: $refCount)';
}
}