mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 09:15:34 +08:00
refs #460 CDataCache for dynamic (downloaded/generated) data with file-based distribution among processes.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user