refs #460 CDataCache for dynamic (downloaded/generated) data with file-based distribution among processes.

This commit is contained in:
Mathew Sutcliffe
2015-09-13 02:08:51 +01:00
parent 56d8bf4651
commit 6601393df8
7 changed files with 296 additions and 2 deletions

View File

@@ -220,6 +220,17 @@ namespace BlackMisc
removeByValueIf(BlackMisc::Predicates::MemberEqual(membFunc, returnValue));
}
//! Remove elements for which the same key/value pair is present in an other dictionary.
void removeDuplicates(const CDictionary &other)
{
for (auto it = begin(); it != end();)
{
auto it2 = other.find(it.key());
if (it2 != other.end() && it.value() == it2.value()) { it = erase(it); }
else { ++it; }
}
}
//! \copydoc CValueObject::toJson
QJsonObject toJson() const
{

View File

@@ -35,6 +35,17 @@ namespace BlackMisc
return id;
}
QUuid CIdentifier::toUuid() const
{
static const QUuid ns = QUuid::createUuid();
QByteArray baseData;
baseData.append(getMachineId());
baseData.append(reinterpret_cast<const char *>(&m_processId), sizeof(m_processId));
baseData.append(reinterpret_cast<const char *>(&m_timestampMSecsSinceEpoch), sizeof(m_timestampMSecsSinceEpoch));
baseData.append(getName());
return QUuid::createUuidV5(ns, baseData);
}
QByteArray CIdentifier::getMachineId() const
{
return QByteArray::fromBase64(m_machineIdBase64.toLocal8Bit());

View File

@@ -49,6 +49,9 @@ namespace BlackMisc
//! Returns an anonymous identifier.
static CIdentifier anonymous();
//! Produces a UUID generated from the identifier.
QUuid toUuid() const;
//! Name
QString getName() const { return m_name; }

View File

@@ -146,7 +146,14 @@ namespace BlackMisc
CStatusMessage CValueCache::saveToFiles(const QString &dir, const QString &keyPrefix) const
{
QMutexLocker lock(&m_mutex);
auto values = getAllValues(keyPrefix);
return saveToFiles(dir, values);
}
CStatusMessage CValueCache::saveToFiles(const QString &dir, const CVariantMap &values) const
{
QMutexLocker lock(&m_mutex);
QMap<QString, CVariantMap> namespaces;
for (auto it = values.cbegin(); it != values.cend(); ++it)
{
@@ -182,10 +189,21 @@ namespace BlackMisc
CStatusMessage CValueCache::loadFromFiles(const QString &dir)
{
QMutexLocker lock(&m_mutex);
CVariantMap values;
auto status = loadFromFiles(dir, values);
insertValues(values);
return status;
}
CStatusMessage CValueCache::loadFromFiles(const QString &dir, CVariantMap &o_values) const
{
QMutexLocker lock(&m_mutex);
if (! QDir(dir).isReadable())
{
return CLogMessage(this).error("Failed to read directory %1") << dir;
}
auto currentValues = getAllValues();
for (const auto &filename : QDir(dir).entryList({ "*.json" }, QDir::Files))
{
QFile file(dir + "/" + filename);
@@ -198,7 +216,10 @@ namespace BlackMisc
{
return CLogMessage(this).error("Invalid JSON format in %1") << file.fileName();
}
loadFromJson(json.object());
CVariantMap temp;
temp.convertFromJson(json.object());
temp.removeDuplicates(currentValues);
o_values.insert(temp);
}
return {};
}

View File

@@ -91,13 +91,22 @@ namespace BlackMisc
//! of CValueCache instances in all processes including this one. The slot will do its own round-trip detection.
void valuesChangedByLocal(const BlackMisc::CVariantMap &values);
protected:
//! Save specific values to Json files in a given directory.
CStatusMessage saveToFiles(const QString &directory, const CVariantMap &values) const;
//! Load from Json files in a given directory any values which differ from the current ones, and insert them in o_values.
CStatusMessage loadFromFiles(const QString &directory, CVariantMap &o_values) const;
//! Mutex protecting operations which are critical on m_elements.
mutable QMutex m_mutex { QMutex::Recursive };
private:
friend class Private::CValuePage;
struct Element;
using ElementPtr = QSharedPointer<Element>; // QMap doesn't support move-only types
QMap<QString, ElementPtr> m_elements;
mutable QMutex m_mutex { QMutex::Recursive };
Element &getElement(const QString &key);
Element &getElement(const QString &key, QMap<QString, ElementPtr>::const_iterator pos);