#ifndef EXPIRINGCACHE_H #define EXPIRINGCACHE_H #include #include #include #include template class ExpiringCache : public QCache { public: ExpiringCache(int maxCost = 100, int expireMs = 1000); ~ExpiringCache(); bool insert(const K& key, V* object, int cost = 1); bool contains(const K& key) const; V* object(const K& key, bool noExpireCheck = false) const; V* operator[](const K& key) const; V* take(const K& key); QList keys() const; bool remove(const K& key); int count() const; void clear(); bool isEmpty() const; void setExpireTime(int ms); private: bool expired(const K& key) const; mutable QHash expires; int expireMs; }; template ExpiringCache::ExpiringCache(int maxCost, int expireMs) : QCache(maxCost), expireMs(expireMs) { } template ExpiringCache::~ExpiringCache() { } template bool ExpiringCache::insert(const K& key, V* object, int cost) { QList keysBefore = QCache::keys(); bool result = QCache::insert(key, object, cost); if (!result) return false; QList keysAfter = QCache::keys(); for (const K& keyBefore : keysBefore) { if (!keysAfter.contains(keyBefore)) expires.remove(keyBefore); } expires[key] = QDateTime::currentMSecsSinceEpoch() + expireMs; return true; } template bool ExpiringCache::contains(const K& key) const { if (expired(key)) return false; return QCache::contains(key); } template V* ExpiringCache::object(const K& key, bool noExpireCheck) const { if (!noExpireCheck && expired(key)) return nullptr; return QCache::object(key); } template V* ExpiringCache::operator[](const K& key) const { if (expired(key)) return nullptr; return QCache::operator[](key); } template V* ExpiringCache::take(const K& key) { if (expired(key)) return nullptr; expires.remove(key); return QCache::take(key); } template QList ExpiringCache::keys() const { QList keyList; for (const K& key : QCache::keys()) { if (!expired(key)) keyList << key; } return keyList; } template bool ExpiringCache::remove(const K& key) { expires.remove(key); return QCache::remove(key); } template int ExpiringCache::count() const { return keys().count(); } template void ExpiringCache::clear() { expires.clear(); QCache::clear(); } template bool ExpiringCache::isEmpty() const { return keys().isEmpty(); } template void ExpiringCache::setExpireTime(int ms) { expireMs = ms; } template bool ExpiringCache::expired(const K& key) const { if (expires.contains(key) && QDateTime::currentMSecsSinceEpoch() > expires[key]) { expires.remove(key); return true; } return false; } #endif // EXPIRINGCACHE_H