mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-02 15:15:50 +08:00
refs #581, #592 Make sure syncLoad checks if the next load would load the value, if it is not currently loading.
This commit is contained in:
@@ -86,12 +86,12 @@ namespace BlackMisc
|
||||
|
||||
std::future<CVariant> 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<CVariant> p;
|
||||
p.set_value(getValueSync(key));
|
||||
@@ -217,7 +217,7 @@ namespace BlackMisc
|
||||
});
|
||||
}
|
||||
|
||||
CDataCacheRevision::LockGuard CDataCacheRevision::beginUpdate(const QMap<QString, qint64> ×tamps)
|
||||
CDataCacheRevision::LockGuard CDataCacheRevision::beginUpdate(const QMap<QString, qint64> ×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<QString>::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<CVariant> CDataCacheRevision::promiseLoadedValue(QObject *pageOwner, const QString &key)
|
||||
std::future<CVariant> CDataCacheRevision::promiseLoadedValue(QObject *pageOwner, const QString &key, qint64 currentTimestamp)
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
|
||||
if (isNewerValueAvailable(key))
|
||||
if (isNewerValueAvailable(key, currentTimestamp))
|
||||
{
|
||||
std::promise<CVariant> promise;
|
||||
auto future = promise.get_future();
|
||||
|
||||
@@ -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<QString, qint64> ×tamps);
|
||||
//! \param updateUuid Whether to prepare for an actual update, or just interrograte whether one is needed.
|
||||
LockGuard beginUpdate(const QMap<QString, qint64> ×tamps, bool updateUuid = true);
|
||||
|
||||
//! During update, writes a new revision file with new timestamps.
|
||||
void writeNewRevision(const QMap<QString, qint64> ×tamps);
|
||||
@@ -64,10 +65,10 @@ namespace BlackMisc
|
||||
QSet<QString> 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<CVariant> promiseLoadedValue(QObject *pageOwner, const QString &key);
|
||||
std::future<CVariant> promiseLoadedValue(QObject *pageOwner, const QString &key, qint64 currentTimestamp);
|
||||
|
||||
//! Returns (by move) the container of promises to load values.
|
||||
std::vector<std::tuple<QObject *, QString, std::promise<CVariant>>> loadedValuePromises();
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user