56 lines
1.4 KiB
Dart
56 lines
1.4 KiB
Dart
import 'memory_cache_store.dart';
|
|
import 'persistent_cache_store.dart';
|
|
|
|
class HybridCacheStore {
|
|
final MemoryCacheStore memory;
|
|
final PersistentCacheStore persistent;
|
|
final Map<String, Future<dynamic>> _inflight = <String, Future<dynamic>>{};
|
|
|
|
HybridCacheStore({required this.memory, required this.persistent});
|
|
|
|
Future<T?> read<T>(String key) async {
|
|
final memoryValue = await memory.read<T>(key);
|
|
if (memoryValue != null) {
|
|
return memoryValue;
|
|
}
|
|
final persistentValue = await persistent.read<T>(key);
|
|
if (persistentValue != null) {
|
|
await memory.write(key, persistentValue);
|
|
}
|
|
return persistentValue;
|
|
}
|
|
|
|
Future<void> write<T>(String key, T value) async {
|
|
await memory.write<T>(key, value);
|
|
await persistent.write<T>(key, value);
|
|
}
|
|
|
|
Future<void> remove(String key) async {
|
|
await memory.remove(key);
|
|
await persistent.remove(key);
|
|
}
|
|
|
|
Future<T> getOrLoad<T>(String key, {required Future<T> Function() loader}) {
|
|
final running = _inflight[key];
|
|
if (running != null) {
|
|
return running.then((value) => value as T);
|
|
}
|
|
|
|
final future = () async {
|
|
final cached = await read<T>(key);
|
|
if (cached != null) {
|
|
return cached;
|
|
}
|
|
|
|
final loaded = await loader();
|
|
await write<T>(key, loaded);
|
|
return loaded;
|
|
}();
|
|
|
|
_inflight[key] = future;
|
|
return future.whenComplete(() {
|
|
_inflight.remove(key);
|
|
});
|
|
}
|
|
}
|