refs #885 Regenerate revision file from available JSON files.

This commit is contained in:
Mathew Sutcliffe
2017-02-19 19:21:30 +00:00
parent e7f61dabea
commit c268581954
4 changed files with 51 additions and 11 deletions

View File

@@ -292,6 +292,12 @@ namespace BlackMisc
if (lock && m_cache->m_revision.isPendingRead()) if (lock && m_cache->m_revision.isPendingRead())
{ {
CValueCachePacket newValues; CValueCachePacket newValues;
if (! m_cache->m_revision.isFound())
{
m_cache->loadFromFiles(persistentStore(), {}, {}, newValues, {}, true);
m_cache->m_revision.regenerate(newValues);
newValues.clear();
}
auto msg = m_cache->loadFromFiles(persistentStore(), m_cache->m_revision.keysWithNewerTimestamps(), baseline.toVariantMap(), newValues, m_cache->m_revision.timestampsAsString()); auto msg = m_cache->loadFromFiles(persistentStore(), m_cache->m_revision.keysWithNewerTimestamps(), baseline.toVariantMap(), newValues, m_cache->m_revision.timestampsAsString());
newValues.setTimestamps(m_cache->m_revision.newerTimestamps()); newValues.setTimestamps(m_cache->m_revision.newerTimestamps());
@@ -364,7 +370,7 @@ namespace BlackMisc
m_originalTimestamps.clear(); m_originalTimestamps.clear();
QFile revisionFile(m_basename + "/.rev"); QFile revisionFile(m_basename + "/.rev");
if (revisionFile.exists()) if ((m_found = revisionFile.exists()))
{ {
if (! revisionFile.open(QFile::ReadOnly | QFile::Text)) if (! revisionFile.open(QFile::ReadOnly | QFile::Text))
{ {
@@ -435,6 +441,7 @@ namespace BlackMisc
if (m_pendingWrite) { return guard; } if (m_pendingWrite) { return guard; }
return {}; return {};
} }
else { m_found = false; }
} }
m_pendingRead = true; m_pendingRead = true;
@@ -483,6 +490,16 @@ namespace BlackMisc
} }
} }
void CDataCacheRevision::regenerate(const CValueCachePacket &keys)
{
QMutexLocker lock(&m_mutex);
Q_ASSERT(m_updateInProgress);
Q_ASSERT(m_lockFile.isLocked());
writeNewRevision(m_originalTimestamps = keys.toTimestampMap());
}
void CDataCacheRevision::finishUpdate(bool keepPromises) void CDataCacheRevision::finishUpdate(bool keepPromises)
{ {
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
@@ -497,12 +514,20 @@ namespace BlackMisc
m_lockFile.unlock(); m_lockFile.unlock();
} }
bool CDataCacheRevision::isFound() const
{
QMutexLocker lock(&m_mutex);
Q_ASSERT(m_updateInProgress);
return m_found;
}
bool CDataCacheRevision::isPendingRead() const bool CDataCacheRevision::isPendingRead() const
{ {
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
Q_ASSERT(m_updateInProgress); Q_ASSERT(m_updateInProgress);
return ! m_timestamps.isEmpty(); return ! m_timestamps.isEmpty() || ! m_found;
} }
void CDataCacheRevision::notifyPendingWrite() void CDataCacheRevision::notifyPendingWrite()

View File

@@ -110,10 +110,16 @@ namespace BlackMisc
//! During update, writes a new revision file with new timestamps. //! During update, writes a new revision file with new timestamps.
void writeNewRevision(const QMap<QString, qint64> &timestamps, const QSet<QString> &excludeKeys = {}); void writeNewRevision(const QMap<QString, qint64> &timestamps, const QSet<QString> &excludeKeys = {});
//! Write a new revision file with keys deduced from the available JSON files.
void regenerate(const CValueCachePacket &keys);
//! Release the revision file lock and mark everything up-to-date (called by LockGuard destructor). //! Release the revision file lock and mark everything up-to-date (called by LockGuard destructor).
//! \param keepPromises Don't break pending promises. //! \param keepPromises Don't break pending promises.
void finishUpdate(bool keepPromises = false); void finishUpdate(bool keepPromises = false);
//! Existing revision file was found.
bool isFound() const;
//! True if beginUpdate found some values with timestamps newer than in memory. //! True if beginUpdate found some values with timestamps newer than in memory.
bool isPendingRead() const; bool isPendingRead() const;
@@ -165,6 +171,7 @@ namespace BlackMisc
private: private:
mutable QMutex m_mutex { QMutex::Recursive }; mutable QMutex m_mutex { QMutex::Recursive };
bool m_updateInProgress = false; bool m_updateInProgress = false;
bool m_found = false;
bool m_pendingRead = false; bool m_pendingRead = false;
bool m_pendingWrite = false; bool m_pendingWrite = false;
QString m_basename; QString m_basename;

View File

@@ -402,7 +402,7 @@ namespace BlackMisc
return status; return status;
} }
CStatusMessage CValueCache::loadFromFiles(const QString &dir, const QSet<QString> &keys, const CVariantMap &currentValues, CValueCachePacket &o_values, const QString &keysMessage) const CStatusMessage CValueCache::loadFromFiles(const QString &dir, const QSet<QString> &keys, const CVariantMap &currentValues, CValueCachePacket &o_values, const QString &keysMessage, bool keysOnly) const
{ {
if (! QDir(dir).exists()) if (! QDir(dir).exists())
{ {
@@ -442,15 +442,23 @@ namespace BlackMisc
{ {
return CStatusMessage(this).error("Invalid JSON format in %1") << file.fileName(); return CStatusMessage(this).error("Invalid JSON format in %1") << file.fileName();
} }
CVariantMap temp; CVariantMap temp;
const QString messagePrefix = QStringLiteral("Parsing %1.json").arg(it.key()); if (keysOnly)
auto messages = temp.convertFromMemoizedJsonNoThrow(json.object(), it.value(), this, messagePrefix);
if (it.value().isEmpty()) { messages.push_back(temp.convertFromMemoizedJsonNoThrow(json.object(), this, messagePrefix)); }
if (! messages.isEmpty())
{ {
ok = false; for (const auto &key : json.object().keys()) { temp.insert(key, {}); }
backupFile(file); }
CLogMessage::preformatted(messages); else
{
const QString messagePrefix = QStringLiteral("Parsing %1.json").arg(it.key());
auto messages = temp.convertFromMemoizedJsonNoThrow(json.object(), it.value(), this, messagePrefix);
if (it.value().isEmpty()) { messages.push_back(temp.convertFromMemoizedJsonNoThrow(json.object(), this, messagePrefix)); }
if (! messages.isEmpty())
{
ok = false;
backupFile(file);
CLogMessage::preformatted(messages);
}
} }
temp.removeDuplicates(currentValues); temp.removeDuplicates(currentValues);
o_values.insert(temp, QFileInfo(file).lastModified().toMSecsSinceEpoch()); o_values.insert(temp, QFileInfo(file).lastModified().toMSecsSinceEpoch());

View File

@@ -284,7 +284,7 @@ namespace BlackMisc
//! Load from Json files in a given directory any values which differ from the current ones, and insert them in o_values. //! Load from Json files in a given directory any values which differ from the current ones, and insert them in o_values.
//! \threadsafe //! \threadsafe
CStatusMessage loadFromFiles(const QString &directory, const QSet<QString> &keys, const CVariantMap &current, CValueCachePacket &o_values, const QString &keysMessage = {}) const; CStatusMessage loadFromFiles(const QString &directory, const QSet<QString> &keys, const CVariantMap &current, CValueCachePacket &o_values, const QString &keysMessage = {}, bool keysOnly = false) const;
//! Mark all values with keys that start with the given prefix as having been saved. //! Mark all values with keys that start with the given prefix as having been saved.
//! \threadsafe //! \threadsafe