From b3e24353733f613df3465f20c520d5b055c4483c Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 4 Aug 2014 17:30:43 +0200 Subject: Be smarter about storing property maps. The current code just dumps such maps into the file via the ">>" operator, so no strings are shared. This patch fixes that. Example results for building Qt Creator: Size of build graph on disk: ~65 MB -> ~34 MB. Size of build graph in memory: ~250MB -> ~150 MB. Change-Id: Ic89d0f6c37ba1cd7b3aa8a35517bb6a6a37061c2 Reviewed-by: Joerg Bornemann --- src/lib/corelib/buildgraph/command.cpp | 4 +- src/lib/corelib/language/language.cpp | 8 +-- src/lib/corelib/language/propertymapinternal.cpp | 4 +- src/lib/corelib/tools/persistence.cpp | 76 +++++++++++++++++++++++- src/lib/corelib/tools/persistence.h | 6 ++ src/lib/corelib/tools/propertyfinder.cpp | 3 +- 6 files changed, 90 insertions(+), 11 deletions(-) diff --git a/src/lib/corelib/buildgraph/command.cpp b/src/lib/corelib/buildgraph/command.cpp index fa7e4cbee..4019bb38e 100644 --- a/src/lib/corelib/buildgraph/command.cpp +++ b/src/lib/corelib/buildgraph/command.cpp @@ -283,14 +283,14 @@ void JavaScriptCommand::load(PersistentPool &pool) { AbstractCommand::load(pool); m_sourceCode = pool.idLoadString(); - pool.stream() >> m_properties; + m_properties = pool.loadVariantMap(); } void JavaScriptCommand::store(PersistentPool &pool) const { AbstractCommand::store(pool); pool.storeString(m_sourceCode); - pool.stream() << m_properties; + pool.store(m_properties); } QList loadCommandList(PersistentPool &pool) diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp index 20ef70b52..5c5fac445 100644 --- a/src/lib/corelib/language/language.cpp +++ b/src/lib/corelib/language/language.cpp @@ -468,7 +468,7 @@ void ResolvedProduct::load(PersistentPool &pool) >> sourceDirectory >> destinationDirectory >> location; - pool.stream() >> productProperties; + productProperties = pool.loadVariantMap(); moduleProperties = pool.idLoadS(); pool.loadContainerS(rules); pool.loadContainerS(dependencies); @@ -493,7 +493,7 @@ void ResolvedProduct::store(PersistentPool &pool) const << destinationDirectory << location; - pool.stream() << productProperties; + pool.store(productProperties); pool.store(moduleProperties); pool.storeContainer(rules); pool.storeContainer(dependencies); @@ -837,7 +837,7 @@ void ResolvedProject::load(PersistentPool &pool) subProjects.append(p); } - pool.stream() >> m_projectProperties; + m_projectProperties = pool.loadVariantMap(); } void ResolvedProject::store(PersistentPool &pool) const @@ -852,7 +852,7 @@ void ResolvedProject::store(PersistentPool &pool) const pool.stream() << subProjects.count(); foreach (const ResolvedProjectConstPtr &project, subProjects) pool.store(project); - pool.stream() << m_projectProperties; + pool.store(m_projectProperties); } diff --git a/src/lib/corelib/language/propertymapinternal.cpp b/src/lib/corelib/language/propertymapinternal.cpp index 89515e74e..31da2dcd3 100644 --- a/src/lib/corelib/language/propertymapinternal.cpp +++ b/src/lib/corelib/language/propertymapinternal.cpp @@ -93,12 +93,12 @@ QString PropertyMapInternal::toJSLiteral() const void PropertyMapInternal::load(PersistentPool &pool) { - pool.stream() >> m_value; + m_value = pool.loadVariantMap(); } void PropertyMapInternal::store(PersistentPool &pool) const { - pool.stream() << m_value; + pool.store(m_value); } } // namespace Internal diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index 0264353d3..5e89b0ce2 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -40,7 +40,7 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-74"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-75"; PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger) { @@ -148,6 +148,80 @@ void PersistentPool::store(const PersistentObject *object) } } +void PersistentPool::store(const QVariantMap &map) +{ + m_stream << map.count(); + for (QVariantMap::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) { + storeString(it.key()); + store(it.value()); + } +} + +QVariantMap PersistentPool::loadVariantMap() +{ + int count; + m_stream >> count; + QVariantMap map; + for (int i = 0; i < count; ++i) { + const QString key = idLoadString(); + const QVariant value = loadVariant(); + map.insert(key, value); + } + return map; +} + +void PersistentPool::store(const QVariant &variant) +{ + const quint32 type = static_cast(variant.type()); + m_stream << type; + switch (type) { + case QMetaType::QString: + storeString(variant.toString()); + break; + case QMetaType::QStringList: + storeStringList(variant.toStringList()); + break; + case QMetaType::QVariantList: + storeContainer(variant.toList()); + break; + case QMetaType::QVariantMap: + store(variant.toMap()); + break; + default: + m_stream << variant; + } +} + +QVariant PersistentPool::loadVariant() +{ + quint32 type; + m_stream >> type; + QVariant value; + switch (type) { + case QMetaType::QString: + value = idLoadString(); + break; + case QMetaType::QStringList: + value = idLoadStringList(); + break; + case QMetaType::QVariantList: { + QVariantList l; + int count; + m_stream >> count; + for (int i = 0; i < count; ++i) + l << loadVariant(); + value = l; + break; + } + case QMetaType::QVariantMap: + value = loadVariantMap(); + break; + default: + m_stream >> value; + } + return value; +} + void PersistentPool::clear() { m_loaded.clear(); diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index 429ff467c..878f22f2a 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -70,6 +70,12 @@ public: void store(const PersistentObject *object); template void storeContainer(const T &container); + void store(const QVariantMap &map); + QVariantMap loadVariantMap(); + + void store(const QVariant &variant); + QVariant loadVariant(); + void storeString(const QString &t); QString loadString(int id); QString idLoadString(); diff --git a/src/lib/corelib/tools/propertyfinder.cpp b/src/lib/corelib/tools/propertyfinder.cpp index 96c081f01..d5ef0d648 100644 --- a/src/lib/corelib/tools/propertyfinder.cpp +++ b/src/lib/corelib/tools/propertyfinder.cpp @@ -82,8 +82,7 @@ void PropertyFinder::findModuleValues(const QVariantMap &properties, bool search void PropertyFinder::addToList(const QVariant &value) { - // Note: This means that manually setting a property to "null" will not lead to a "hit". - if (!value.isNull() && !m_values.contains(value)) + if (value.isValid() && !m_values.contains(value)) m_values << value; } -- cgit v1.2.3