From 29cea55bc92888ecf7b8a098e7b4569edc6b0510 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Thu, 26 May 2016 20:03:13 +0100 Subject: [PATCH] refs #659 Allow setting a "deferred" flag in data cache values, causing the value not to be loaded. --- src/blackmisc/datacache.cpp | 19 +++++++++++++++++++ src/blackmisc/datacache.h | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/blackmisc/datacache.cpp b/src/blackmisc/datacache.cpp index 3ff0319a7..3d06c4398 100644 --- a/src/blackmisc/datacache.cpp +++ b/src/blackmisc/datacache.cpp @@ -140,6 +140,11 @@ namespace BlackMisc QTimer::singleShot(0, &m_serializer, [this, key] { m_revision.pinValue(key); }); } + void CDataCache::deferValue(const QString &key) + { + QTimer::singleShot(0, &m_serializer, [this, key] { m_revision.deferValue(key); }); + } + QString lockFileError(const QLockFile &lock) { switch (lock.error()) @@ -352,6 +357,12 @@ namespace BlackMisc if (! pins.contains(key)) { m_timestamps.remove(key); } } } + + auto deferrals = fromJson(json.value("deferrals").toArray()); + for (const auto &key : m_timestamps.keys()) + { + if (deferrals.contains(key)) { m_timestamps.remove(key); } + } } else if (revisionFile.size() > 0) { @@ -393,6 +404,7 @@ namespace BlackMisc json.insert("timestamps", toJson(timestamps)); json.insert("ttl", toJson(m_timesToLive)); json.insert("pins", toJson(m_pinnedValues)); + json.insert("deferrals", toJson(m_deferredValues)); revisionFile.write(QJsonDocument(json).toJson()); } @@ -542,6 +554,13 @@ namespace BlackMisc m_pinnedValues.insert(key); } + void CDataCacheRevision::deferValue(const QString &key) + { + Q_ASSERT(! m_updateInProgress); + + m_deferredValues.insert(key); + } + QJsonObject CDataCacheRevision::toJson(const QMap ×tamps) { QJsonObject result; diff --git a/src/blackmisc/datacache.h b/src/blackmisc/datacache.h index a95afdd2a..6f84456f7 100644 --- a/src/blackmisc/datacache.h +++ b/src/blackmisc/datacache.h @@ -144,6 +144,9 @@ namespace BlackMisc //! Set the flag which will cause the value to be pre-loaded. void pinValue(const QString &key); + //! Set the flag which will cause the value to be deferred-loaded. + void deferValue(const QString &key); + private: mutable QMutex m_mutex { QMutex::Recursive }; bool m_updateInProgress = false; @@ -155,6 +158,7 @@ namespace BlackMisc QMap m_timestamps; QMap m_timesToLive; QSet m_pinnedValues; + QSet m_deferredValues; std::vector> m_promises; static QJsonObject toJson(const QMap ×tamps); @@ -235,6 +239,9 @@ namespace BlackMisc //! Method used for implementing pinning values. void pinValue(const QString &key); + //! Method used for implementing deferring values. + void deferValue(const QString &key); + private: CDataCache(); @@ -273,6 +280,8 @@ namespace BlackMisc { if (Trait::timeToLive() >= 0) { CDataCache::instance()->setTimeToLive(Trait::key(), Trait::timeToLive()); } if (Trait::isPinned()) { CDataCache::instance()->pinValue(Trait::key()); } + if (Trait::isDeferred()) { CDataCache::instance()->deferValue(Trait::key()); } + static_assert(! (Trait::isPinned() && Trait::isDeferred()), "trait can not be both pinned and deferred"); } //! Reset the data to its default value. @@ -334,6 +343,10 @@ namespace BlackMisc //! Good for small, important values; bad for large ones. static constexpr bool isPinned() { return false; } + //! If true, then value will not be loaded until it is explicitly admitted. + //! Good for large values the loading of which might depend on some other condition. + static constexpr bool isDeferred() { return false; } + //! Deleted default constructor. CDataTrait() = delete;