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())
{
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());
newValues.setTimestamps(m_cache->m_revision.newerTimestamps());
@@ -364,7 +370,7 @@ namespace BlackMisc
m_originalTimestamps.clear();
QFile revisionFile(m_basename + "/.rev");
if (revisionFile.exists())
if ((m_found = revisionFile.exists()))
{
if (! revisionFile.open(QFile::ReadOnly | QFile::Text))
{
@@ -435,6 +441,7 @@ namespace BlackMisc
if (m_pendingWrite) { return guard; }
return {};
}
else { m_found = false; }
}
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)
{
QMutexLocker lock(&m_mutex);
@@ -497,12 +514,20 @@ namespace BlackMisc
m_lockFile.unlock();
}
bool CDataCacheRevision::isFound() const
{
QMutexLocker lock(&m_mutex);
Q_ASSERT(m_updateInProgress);
return m_found;
}
bool CDataCacheRevision::isPendingRead() const
{
QMutexLocker lock(&m_mutex);
Q_ASSERT(m_updateInProgress);
return ! m_timestamps.isEmpty();
return ! m_timestamps.isEmpty() || ! m_found;
}
void CDataCacheRevision::notifyPendingWrite()

View File

@@ -110,10 +110,16 @@ namespace BlackMisc
//! During update, writes a new revision file with new timestamps.
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).
//! \param keepPromises Don't break pending promises.
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.
bool isPendingRead() const;
@@ -165,6 +171,7 @@ namespace BlackMisc
private:
mutable QMutex m_mutex { QMutex::Recursive };
bool m_updateInProgress = false;
bool m_found = false;
bool m_pendingRead = false;
bool m_pendingWrite = false;
QString m_basename;

View File

@@ -402,7 +402,7 @@ namespace BlackMisc
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())
{
@@ -442,15 +442,23 @@ namespace BlackMisc
{
return CStatusMessage(this).error("Invalid JSON format in %1") << file.fileName();
}
CVariantMap temp;
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())
if (keysOnly)
{
ok = false;
backupFile(file);
CLogMessage::preformatted(messages);
for (const auto &key : json.object().keys()) { temp.insert(key, {}); }
}
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);
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.
//! \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.
//! \threadsafe