get method
Returns the cache value for the specified key
.
key
: the keydelegate
: provides the caller a way of changing the CacheEntry before persistence
Implementation
@override
Future<T?> get(String key, {CacheEntryDelegate<T>? delegate}) {
// Current time
final now = clock.now();
// #region Statistics
Stopwatch? watch;
Future<CacheEntry?> Function(CacheEntry? entry) posGet1 =
(CacheEntry? entry) => Future.value(entry);
Future<T?> Function(T? value) posGet2 = (T? value) => Future.value(value);
if (statsEnabled) {
watch = clock.stopwatch()..start();
posGet1 = (CacheEntry? entry) {
if (entry == null || entry.isExpired(now)) {
stats.increaseMisses();
} else {
stats.increaseGets();
}
return Future.value(entry);
};
posGet2 = (T? value) {
if (watch != null) {
stats.addGetTime(watch.elapsedMicroseconds);
watch.stop();
}
return Future.value(value);
};
}
// #endregion
// Gets the entry from the storage
return _getStorageEntry(key).then(posGet1).then((entry) {
final expired = entry != null && entry.isExpired(now);
// Does this entry exists or is expired ?
if (entry == null || expired) {
// If expired we need to remove the value from the storage
final pre = expired
? _removeStorageEntry(
key, CacheEntryExpiredEvent<T>(this, entry.info))
: Future<void>.value();
// Invoke the cache loader
return pre.then((_) => cacheLoader(key)).then((value) {
// If the value obtained is `null` just return it
if (value == null) {
return Future<T?>.value();
}
return _newEntry(_entryBuilder(key, value, now, delegate: delegate))
.then((_) => value);
}).then(posGet2);
} else {
return _getEntryValue(entry, now).then(posGet2);
}
});
}