import 'dart:collection'; /// Bounded in-memory LRU cache where each entry expires after [ttl]. class TtlCache { final Duration ttl; final int maxEntries; final LinkedHashMap> _entries = LinkedHashMap>(); TtlCache(this.ttl, {this.maxEntries = 100}) { if (maxEntries <= 0) { throw ArgumentError.value( maxEntries, 'maxEntries', 'must be greater than zero', ); } } T? get(String key) { _removeExpired(); final entry = _entries[key]; if (entry == null) return null; // LinkedHashMap preserves insertion order, so reinserting makes this the // most recently used entry. _entries ..remove(key) ..[key] = entry; return entry.value; } void set(String key, T value) { _removeExpired(); _entries.remove(key); _entries[key] = _TtlEntry(value, DateTime.now().add(ttl)); while (_entries.length > maxEntries) { _entries.remove(_entries.keys.first); } } void remove(String key) => _entries.remove(key); void clear() => _entries.clear(); int get length { _removeExpired(); return _entries.length; } void _removeExpired() { if (_entries.isEmpty) return; final now = DateTime.now(); _entries.removeWhere((_, entry) => !now.isBefore(entry.expiresAt)); } } class _TtlEntry { final T value; final DateTime expiresAt; _TtlEntry(this.value, this.expiresAt); }