diff --git a/src/blackmisc/datacache.cpp b/src/blackmisc/datacache.cpp index 580ce4072..11a8c590e 100644 --- a/src/blackmisc/datacache.cpp +++ b/src/blackmisc/datacache.cpp @@ -135,6 +135,11 @@ namespace BlackMisc QTimer::singleShot(0, &m_serializer, [this, key, timestamp] { m_revision.overrideTimestamp(key, timestamp); }); } + qint64 CDataCache::getTimestampOnDisk(const QString &key) + { + return m_revision.getTimestampOnDisk(key); + } + void CDataCache::pinValue(const QString &key) { QTimer::singleShot(0, &m_serializer, [this, key] { m_revision.pinValue(key); }); @@ -558,6 +563,37 @@ namespace BlackMisc m_lockFile.unlock(); } + qint64 CDataCacheRevision::getTimestampOnDisk(const QString &key) + { + QMutexLocker lock(&m_mutex); + + if (m_lockFile.isLocked()) { return m_timestamps.value(key); } + + if (! m_lockFile.lock()) + { + CLogMessage(this).error("Failed to lock %1: %2") << m_basename << lockFileError(m_lockFile); + m_lockFile.unlock(); + return 0; + } + + qint64 result = 0; + QFile revisionFile(m_basename + "/.rev"); + if (revisionFile.exists()) + { + if (revisionFile.open(QFile::ReadOnly | QFile::Text)) + { + auto json = QJsonDocument::fromJson(revisionFile.readAll()).object(); + result = static_cast(json.value("timestamps").toObject().value(key).toDouble()); + } + else + { + CLogMessage(this).error("Failed to open %1: %2") << revisionFile.fileName() << revisionFile.errorString(); + } + } + m_lockFile.unlock(); + return result; + } + void CDataCacheRevision::pinValue(const QString &key) { Q_ASSERT(! m_updateInProgress); diff --git a/src/blackmisc/datacache.h b/src/blackmisc/datacache.h index 7fa8bcb3b..235a74dcd 100644 --- a/src/blackmisc/datacache.h +++ b/src/blackmisc/datacache.h @@ -141,6 +141,9 @@ namespace BlackMisc //! Causes the new timestamp to be written to the revision file. void overrideTimestamp(const QString &key, qint64 timestamp); + //! Read the revision file to get a timestamp. + qint64 getTimestampOnDisk(const QString &key); + //! Set the flag which will cause the value to be pre-loaded. void pinValue(const QString &key); @@ -241,6 +244,9 @@ namespace BlackMisc //! Method used for implementing timestamp renewal. void renewTimestamp(const QString &key, qint64 timestamp); + //! Method used for implementing loading timestamp without value. + qint64 getTimestampOnDisk(const QString &key); + //! Method used for implementing pinning values. void pinValue(const QString &key); @@ -311,6 +317,13 @@ namespace BlackMisc //! Don't change the value, but write a new timestamp, to extend the life of the value. void renewTimestamp(qint64 timestamp) { return CDataCache::instance()->renewTimestamp(this->getKey(), timestamp); } + //! Get the timestamp of the value, or of the deferred value that is available to be loaded. + QDateTime getAvailableTimestamp() const + { + if (Trait::isDeferred()) { return QDateTime::fromMSecsSinceEpoch(CDataCache::instance()->getTimestampOnDisk(this->getKey())); } + return this->getTimestamp(); + } + //! If the value is load-deferred, trigger the deferred load (async). void admit() { if (Trait::isDeferred()) { CDataCache::instance()->admitValue(Trait::key(), true); } }