get method

  1. @override
Future get(
  1. String key
)
override

Retrieves a value from the cache by its key.

Returns the cached value associated with the key if it exists and has not expired. If the key does not exist or has expired, returns null.

Throws an exception if the key is null or empty. Implementations should handle deserialization of the stored value if necessary.

  • Parameters:
    • key: A non-null, non-empty string representing the cache key.
  • Returns: The cached value, or null if not found or expired.

Implementation

@override
Future<dynamic> get(String key) async {
  if (key.isEmpty) {
    throw ArgumentError('Cache key cannot be empty');
  }

  final filePath = _getFilePath(key);
  final file = File(filePath);

  if (!await file.exists()) {
    _stats.misses++;
    await _saveMetadata();
    return null;
  }

  try {
    var encodedData = await file.readAsString();
    final isCompressed =
        encodedData.startsWith('H4sI'); // Gzip magic bytes in base64

    Map<String, dynamic> data;

    if (isCompressed) {
      // Decompress the data
      try {
        final compressedBytes = base64Decode(encodedData);
        final decompressedBytes = gzip.decode(compressedBytes);
        encodedData = utf8.decode(decompressedBytes);
        data = jsonDecode(encodedData);
      } catch (e) {
        // If decompression fails, treat as corrupted
        throw const FormatException('Failed to decompress cache data');
      }
    } else {
      data = jsonDecode(encodedData);
    }

    final expiresAt = DateTime.parse(data['expires_at']);
    final now = DateTime.now();

    if (now.isAfter(expiresAt)) {
      // Cache expired, remove file
      await forget(key);
      _stats.misses++;
      _stats.expirations++;
      await _saveMetadata();
      return null;
    }

    // Update statistics
    _stats.hits++;
    await _saveMetadata();

    // Return the value
    return data['value'];
  } catch (e) {
    // If file is corrupted, remove it
    try {
      await file.delete();
    } catch (_) {
      // Ignore deletion errors
    }
    _stats.misses++;
    await _saveMetadata();
    return null;
  }
}