putAll<T> method
Future<void>
putAll<T>(
- Map<
String, T> entries, { - Duration? expiry,
- Duration? slidingExpiry,
- CachePolicy? policy,
Stores multiple values in the cache with the given keys.
The entries
parameter is a map where the keys are the cache keys and the values are the values to store.
The expiry
parameter can be used to set an optional expiry time for all the data.
The slidingExpiry
parameter can be used to set an optional sliding expiry time for all the data.
The policy
parameter can be used to set a cache policy for all the data.
If both individual parameters (expiry, slidingExpiry) and a policy are provided, the individual parameters will take precedence over the policy.
Throws a CacheException if there is an error storing the data.
Implementation
Future<void> putAll<T>(
Map<String, T> entries, {
Duration? expiry,
Duration? slidingExpiry,
CachePolicy? policy,
}) async {
try {
final effectivePolicy = policy ?? CachePolicy.defaultPolicy;
final effectiveExpiry = expiry ?? effectivePolicy.expiry;
final effectiveSlidingExpiry =
slidingExpiry ?? effectivePolicy.slidingExpiry;
final cacheItems = <String, CacheItem<dynamic>>{};
final now = DateTime.now();
final expiryTime =
effectiveExpiry != null ? now.add(effectiveExpiry) : null;
for (final entry in entries.entries) {
final key = entry.key;
final value = entry.value;
// Initialize compression variables
bool isCompressed = false;
int? originalSize;
double? compressionRatio;
dynamic finalValue = value;
// Check if compression should be applied
if (effectivePolicy.compression != CompressionMode.never &&
_compression != null &&
value is String) {
// For auto mode, check if compression is beneficial
if (effectivePolicy.compression == CompressionMode.auto) {
if (_compression.shouldCompress(value)) {
// Compress the value
originalSize =
value.length * 2; // Rough estimate: 2 bytes per character
final compressedValue = _compression.compressString(value);
compressionRatio = originalSize / (compressedValue.length * 2);
// Only use compression if it actually reduces the size
if (compressionRatio > 1.1) {
// At least 10% reduction
finalValue = compressedValue;
isCompressed = true;
_log.fine(
'Compressed value for key $key with ratio $compressionRatio');
}
}
} else if (effectivePolicy.compression == CompressionMode.always) {
// Always compress
originalSize = value.length * 2;
final compressedValue = _compression.compressString(value);
compressionRatio = originalSize / (compressedValue.length * 2);
finalValue = compressedValue;
isCompressed = true;
_log.fine(
'Compressed value for key $key with ratio $compressionRatio');
}
}
final cacheItem = CacheItem<T>(
value: finalValue as T,
expiry: expiryTime,
slidingExpiry: effectiveSlidingExpiry,
priority: effectivePolicy.priority,
isCompressed: isCompressed,
originalSize: originalSize,
compressionRatio: compressionRatio,
);
// Check if the item exceeds the maximum size (if specified)
if (effectivePolicy.maxSize != null) {
// This is a simple estimation of the size, not exact
final jsonString = cacheItem.toJson().toString();
final estimatedSize =
jsonString.length * 2; // Rough estimate: 2 bytes per character
if (estimatedSize > effectivePolicy.maxSize!) {
_log.warning(
'Item exceeds maximum size: $estimatedSize > ${effectivePolicy.maxSize}');
// Skip this item but continue with others
continue;
}
}
cacheItems[key] = cacheItem;
}
if (cacheItems.isEmpty) {
_log.warning('No items to cache after size filtering');
return;
}
await _cacheAdapter.putAll(cacheItems);
// Check if we need to evict items
if (_eviction != null) {
await _eviction.checkAndEvict();
}
} on HiveError catch (e) {
_log.severe('Failed to put data into cache (HiveError): $e');
throw CacheException('Failed to put data into cache: ${e.message}');
} catch (e) {
_log.severe('Failed to put data into cache (Unknown Error): $e');
throw CacheException('Failed to put data into cache: $e');
}
}