mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-05 01:05:34 +08:00
refs #545 CValueCache keeps track of which values have been saved.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
namespace BlackMisc
|
||||
{
|
||||
CDataCache::CDataCache() :
|
||||
CValueCache(CValueCache::LocalOnly) // for signal loopback
|
||||
CValueCache(CValueCache::Distributed)
|
||||
{
|
||||
if (! QDir::root().mkpath(persistentStore()))
|
||||
{
|
||||
@@ -24,6 +24,11 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
connect(this, &CValueCache::valuesChangedByLocal, this, &CDataCache::saveToStoreAsync);
|
||||
connect(this, &CValueCache::valuesChangedByLocal, this, [ = ](CValueCachePacket values)
|
||||
{
|
||||
values.setSaved();
|
||||
changeValuesFromRemote(values, CIdentifier());
|
||||
});
|
||||
connect(&m_watcher, &QFileSystemWatcher::fileChanged, this, &CDataCache::loadFromStoreAsync);
|
||||
connect(&m_serializer, &CDataCacheSerializer::valuesLoadedFromStore, this, &CDataCache::changeValuesFromRemote);
|
||||
|
||||
@@ -127,6 +132,7 @@ namespace BlackMisc
|
||||
|
||||
if (! m_deferredChanges.isEmpty()) // apply changes which we grabbed at the last minute above
|
||||
{
|
||||
m_deferredChanges.setSaved();
|
||||
emit valuesLoadedFromStore(m_deferredChanges, CIdentifier::anonymous());
|
||||
m_deferredChanges.clear();
|
||||
}
|
||||
@@ -163,6 +169,7 @@ namespace BlackMisc
|
||||
|
||||
if (! (m_deferredChanges.isEmpty() || defer))
|
||||
{
|
||||
m_deferredChanges.setSaved();
|
||||
emit valuesLoadedFromStore(m_deferredChanges, CIdentifier::anonymous());
|
||||
m_deferredChanges.clear();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace BlackMisc
|
||||
return dir;
|
||||
}
|
||||
|
||||
BlackMisc::CStatusMessage CSettingsCache::saveToStore(const QString &keyPrefix) const
|
||||
BlackMisc::CStatusMessage CSettingsCache::saveToStore(const QString &keyPrefix)
|
||||
{
|
||||
return saveToFiles(persistentStore(), keyPrefix);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace BlackMisc
|
||||
static const QString &persistentStore();
|
||||
|
||||
//! Save core settings to disk.
|
||||
BlackMisc::CStatusMessage saveToStore(const QString &keyPrefix = {}) const;
|
||||
BlackMisc::CStatusMessage saveToStore(const QString &keyPrefix = {});
|
||||
|
||||
//! Load core settings from disk.
|
||||
BlackMisc::CStatusMessage loadFromStore();
|
||||
|
||||
@@ -29,7 +29,8 @@ namespace BlackMisc
|
||||
// CValueCachePacket
|
||||
////////////////////////////////
|
||||
|
||||
CValueCachePacket::CValueCachePacket(const CVariantMap &values, qint64 timestamp)
|
||||
CValueCachePacket::CValueCachePacket(const CVariantMap &values, qint64 timestamp, bool saved) :
|
||||
m_saved(saved)
|
||||
{
|
||||
for (auto it = values.cbegin(); it != values.cend(); ++it)
|
||||
{
|
||||
@@ -89,6 +90,7 @@ namespace BlackMisc
|
||||
const QString m_key;
|
||||
CVariant m_value;
|
||||
int m_pendingChanges = 0;
|
||||
bool m_saved = false;
|
||||
std::atomic<qint64> m_timestamp { QDateTime::currentMSecsSinceEpoch() };
|
||||
};
|
||||
|
||||
@@ -156,6 +158,7 @@ namespace BlackMisc
|
||||
element.m_pendingChanges++;
|
||||
element.m_value = in.value();
|
||||
element.m_timestamp = in.timestamp();
|
||||
element.m_saved = values.isSaved();
|
||||
}
|
||||
emit valuesChanged(values, sender());
|
||||
emit valuesChangedByLocal(values);
|
||||
@@ -182,6 +185,7 @@ namespace BlackMisc
|
||||
{
|
||||
element.m_value = in.value();
|
||||
element.m_timestamp = in.timestamp();
|
||||
element.m_saved = values.isSaved();
|
||||
ratifiedChanges.insert(in.key(), in.value(), in.timestamp());
|
||||
}
|
||||
}
|
||||
@@ -203,11 +207,13 @@ namespace BlackMisc
|
||||
insertValues({ map, QDateTime::currentMSecsSinceEpoch() });
|
||||
}
|
||||
|
||||
CStatusMessage CValueCache::saveToFiles(const QString &dir, const QString &keyPrefix) const
|
||||
CStatusMessage CValueCache::saveToFiles(const QString &dir, const QString &keyPrefix)
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
auto values = getAllValues(keyPrefix);
|
||||
return saveToFiles(dir, values);
|
||||
auto status = saveToFiles(dir, values);
|
||||
if (! status.isEmpty()) { markAllAsSaved(keyPrefix); }
|
||||
return status;
|
||||
}
|
||||
|
||||
CStatusMessage CValueCache::saveToFiles(const QString &dir, const CVariantMap &values) const
|
||||
@@ -250,6 +256,7 @@ namespace BlackMisc
|
||||
QMutexLocker lock(&m_mutex);
|
||||
CValueCachePacket values;
|
||||
auto status = loadFromFiles(dir, getAllValues(), values);
|
||||
values.setSaved();
|
||||
insertValues(values);
|
||||
return status;
|
||||
}
|
||||
@@ -280,6 +287,15 @@ namespace BlackMisc
|
||||
return {};
|
||||
}
|
||||
|
||||
void CValueCache::markAllAsSaved(const QString &keyPrefix)
|
||||
{
|
||||
QMutexLocker lock(&m_mutex);
|
||||
for (const auto &element : elementsStartingWith(keyPrefix))
|
||||
{
|
||||
element->m_saved = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString CValueCache::filenameForKey(const QString &key)
|
||||
{
|
||||
return key.section('/', 0, 0) + ".json";
|
||||
|
||||
@@ -23,14 +23,29 @@ namespace BlackMisc
|
||||
*/
|
||||
class BLACKMISC_EXPORT CValueCachePacket :
|
||||
public CDictionary<QString, std::pair<CVariant, qint64>, QMap>,
|
||||
public Mixin::MetaType<CValueCachePacket>
|
||||
public Mixin::MetaType<CValueCachePacket>,
|
||||
public Mixin::DBusByTuple<CValueCachePacket>,
|
||||
public Mixin::JsonByTuple<CValueCachePacket>,
|
||||
public Mixin::EqualsByTuple<CValueCachePacket>
|
||||
{
|
||||
public:
|
||||
//! Default constructor.
|
||||
CValueCachePacket() {}
|
||||
BLACKMISC_DECLARE_USING_MIXIN_DBUS(CValueCachePacket)
|
||||
BLACKMISC_DECLARE_USING_MIXIN_JSON(CValueCachePacket)
|
||||
|
||||
//! \copydoc BlackMisc::CValueObject::base_type
|
||||
using base_type = CDictionary;
|
||||
|
||||
//! Constructor.
|
||||
CValueCachePacket(bool saved = false) : m_saved(saved) {}
|
||||
|
||||
//! Construct from CVariantMap and a timestamp.
|
||||
CValueCachePacket(const CVariantMap &values, qint64 timestamp);
|
||||
CValueCachePacket(const CVariantMap &values, qint64 timestamp, bool saved = false);
|
||||
|
||||
//! Values are to be saved.
|
||||
//! @{
|
||||
bool isSaved() const { return m_saved; }
|
||||
void setSaved(bool saved = true) { m_saved = saved; }
|
||||
//! @}
|
||||
|
||||
//! Insert a key/value pair with a timestamp.
|
||||
void insert(const QString &key, const CVariant &value, qint64 timestamp);
|
||||
@@ -67,6 +82,10 @@ namespace BlackMisc
|
||||
const_iterator begin() const { return CDictionary::cbegin(); }
|
||||
const_iterator end() const { return CDictionary::cend(); }
|
||||
//! @}
|
||||
|
||||
private:
|
||||
BLACK_ENABLE_TUPLE_CONVERSION(CValueCachePacket)
|
||||
bool m_saved = false;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -118,7 +137,7 @@ namespace BlackMisc
|
||||
//! Save values to Json files in a given directory.
|
||||
//! If prefix is provided then only those values whose keys start with that prefix.
|
||||
//! \threadsafe
|
||||
CStatusMessage saveToFiles(const QString &directory, const QString &keyPrefix = {}) const;
|
||||
CStatusMessage saveToFiles(const QString &directory, const QString &keyPrefix = {});
|
||||
|
||||
//! Load all values from Json files in a given directory.
|
||||
//! Values already in the cache will remain in the cache unless they are overwritten.
|
||||
@@ -186,6 +205,10 @@ namespace BlackMisc
|
||||
//! \threadsafe
|
||||
CStatusMessage loadFromFiles(const QString &directory, const CVariantMap ¤t, CValueCachePacket &o_values) const;
|
||||
|
||||
//! Mark all values with keys that start with the given prefix as having been saved.
|
||||
//! \threadsafe
|
||||
void markAllAsSaved(const QString &keyPrefix);
|
||||
|
||||
//! Mutex protecting operations which are critical on m_elements.
|
||||
mutable QMutex m_mutex { QMutex::Recursive };
|
||||
|
||||
@@ -308,5 +331,6 @@ namespace BlackMisc
|
||||
} // namespace
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::CValueCachePacket)
|
||||
BLACK_DECLARE_TUPLE_CONVERSION(BlackMisc::CValueCachePacket, (attr(o.m_saved)))
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user