From a58dddfa191502d9a9b9c52f82fccf5bb8eb42de Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sat, 6 Feb 2016 18:40:31 +0000 Subject: [PATCH] refs #581, #592 Make sure syncLoad checks if the next load would load the value, if it is not currently loading. --- src/blackmisc/datacache.cpp | 16 ++++++++-------- src/blackmisc/datacache.h | 7 ++++--- src/blackmisc/valuecache.h | 4 ++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/blackmisc/datacache.cpp b/src/blackmisc/datacache.cpp index e81d8a20b..478ba65df 100644 --- a/src/blackmisc/datacache.cpp +++ b/src/blackmisc/datacache.cpp @@ -86,12 +86,12 @@ namespace BlackMisc std::future CDataCache::syncLoad(QObject *pageOwner, const QString &key) { - auto future = m_revision.promiseLoadedValue(pageOwner, key); + auto future = m_revision.promiseLoadedValue(pageOwner, key, getTimestampSync(key)); if (future.valid()) { return future; } - else // value is not currently loading, so immediately return the current value + else // value is not awaiting load, so immediately return the current value { std::promise p; p.set_value(getValueSync(key)); @@ -217,7 +217,7 @@ namespace BlackMisc }); } - CDataCacheRevision::LockGuard CDataCacheRevision::beginUpdate(const QMap ×tamps) + CDataCacheRevision::LockGuard CDataCacheRevision::beginUpdate(const QMap ×tamps, bool updateUuid) { QMutexLocker lock(&m_mutex); @@ -253,7 +253,7 @@ namespace BlackMisc if (m_pendingWrite) { return guard; } return {}; } - m_uuid = uuid; + if (updateUuid) { m_uuid = uuid; } auto timesToLive = fromJson(json.value("ttl").toObject()); auto newTimestamps = fromJson(json.value("timestamps").toObject()); @@ -348,18 +348,18 @@ namespace BlackMisc return QSet::fromList(m_timestamps.keys()); } - bool CDataCacheRevision::isNewerValueAvailable(const QString &key) const + bool CDataCacheRevision::isNewerValueAvailable(const QString &key, qint64 timestamp) { QMutexLocker lock(&m_mutex); - return m_updateInProgress && m_timestamps.contains(key); + return (m_updateInProgress || beginUpdate({{ key, timestamp }}, false)) && m_timestamps.contains(key); } - std::future CDataCacheRevision::promiseLoadedValue(QObject *pageOwner, const QString &key) + std::future CDataCacheRevision::promiseLoadedValue(QObject *pageOwner, const QString &key, qint64 currentTimestamp) { QMutexLocker lock(&m_mutex); - if (isNewerValueAvailable(key)) + if (isNewerValueAvailable(key, currentTimestamp)) { std::promise promise; auto future = promise.get_future(); diff --git a/src/blackmisc/datacache.h b/src/blackmisc/datacache.h index a3ae2521a..94f1ecf19 100644 --- a/src/blackmisc/datacache.h +++ b/src/blackmisc/datacache.h @@ -46,7 +46,8 @@ namespace BlackMisc //! Get the state of the disk cache, and prepare to update any values which are out of date. //! Return value can be converted to bool, false means update is not started (error, or already up-to-date). //! \param timestamps Current in-memory timestamps, to be compared with the on-disk ones. - LockGuard beginUpdate(const QMap ×tamps); + //! \param updateUuid Whether to prepare for an actual update, or just interrograte whether one is needed. + LockGuard beginUpdate(const QMap ×tamps, bool updateUuid = true); //! During update, writes a new revision file with new timestamps. void writeNewRevision(const QMap ×tamps); @@ -64,10 +65,10 @@ namespace BlackMisc QSet keysWithNewerTimestamps() const; //! During update, returns true if the on-disk timestamp of this key is newer than in-memory. - bool isNewerValueAvailable(const QString &key) const; + bool isNewerValueAvailable(const QString &key, qint64 timestamp); //! Return a future which will be made ready when the value is loaded. Future is invalid if value is not loading. - std::future promiseLoadedValue(QObject *pageOwner, const QString &key); + std::future promiseLoadedValue(QObject *pageOwner, const QString &key, qint64 currentTimestamp); //! Returns (by move) the container of promises to load values. std::vector>> loadedValuePromises(); diff --git a/src/blackmisc/valuecache.h b/src/blackmisc/valuecache.h index 348158fc8..cff311667 100644 --- a/src/blackmisc/valuecache.h +++ b/src/blackmisc/valuecache.h @@ -229,6 +229,10 @@ namespace BlackMisc //! \threadsafe CVariant getValueSync(const QString &key) { return std::get<0>(getValue(key)); } + //! Synchronously return a current timestamp. + //! \threadsafe + qint64 getTimestampSync(const QString &key) { return std::get<1>(getValue(key)); } + private: friend class Private::CValuePage; struct Element;