]> git.pld-linux.org Git - packages/akonadi.git/blame - 0020-Avoid-ridiculous-amount-of-SQL-queries-by-caching-Pa.patch
boost rebuild
[packages/akonadi.git] / 0020-Avoid-ridiculous-amount-of-SQL-queries-by-caching-Pa.patch
CommitLineData
8a8f9fb3
AM
1From 215b188d891d5236fe94131d176d7ddc3ae02d5d Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
3Date: Fri, 5 Dec 2014 17:12:28 +0100
4Subject: [PATCH 20/30] Avoid ridiculous amount of SQL queries by caching
5 PartTypes
6
7PartTypes are identified by their FQ name, which is in form NAMESPACE:NAME,
8where namespace and name are stored in individual columns. For this reason
9the standard ::retrieveByName() and name cache generated from entities.xslt
10does not work. This patch adds special handling for PartType table, so that
11a special PartType::retrieveByFQName() method as well as PartType name cache
12handling are generated during the XSL Transformation, allowing us to cache
13all the PartTypes.
14
15This reduces the amount of SQL queries by at least two for each single AKAPPEND,
16MERGE, STORE and FETCH command, providing a nice performance boost during
17sync.
18---
19 server/src/handler/append.cpp | 4 ++--
20 server/src/storage/datastore.cpp | 4 +++-
21 server/src/storage/entities-header.xsl | 7 ++++++-
22 server/src/storage/entities-source.xsl | 31 ++++++++++++++++++++++++++++++-
23 server/src/storage/entities.xsl | 7 ++++++-
24 server/src/storage/parttypehelper.cpp | 29 +----------------------------
25 server/src/storage/parttypehelper.h | 13 -------------
26 7 files changed, 48 insertions(+), 47 deletions(-)
27
28diff --git a/server/src/handler/append.cpp b/server/src/handler/append.cpp
29index c503216..b594e27 100644
30--- a/server/src/handler/append.cpp
31+++ b/server/src/handler/append.cpp
32@@ -134,7 +134,7 @@ bool Append::commit()
33
34 // wrap data into a part
35 Part part;
36- part.setPartType( PartTypeHelper::fromName( "PLD", "RFC822" ) );
37+ part.setPartType( PartType::retrieveByFQName( QLatin1String("PLD"), QLatin1String("RFC822") ) );
38 part.setData( m_data );
39 part.setPimItemId( item.id() );
40 part.setDatasize( dataSize );
41@@ -148,7 +148,7 @@ bool Append::commit()
42 //akDebug() << "Append handler: doPreprocessing is" << doPreprocessing;
43 if ( doPreprocessing ) {
44 Part hiddenAttribute;
45- hiddenAttribute.setPartType( PartTypeHelper::fromName( "ATR", "HIDDEN" ) );
46+ hiddenAttribute.setPartType( PartType::retrieveByFQName( QLatin1String("ATR"), QLatin1String("HIDDEN") ) );
47 hiddenAttribute.setData( QByteArray() );
48 hiddenAttribute.setPimItemId( item.id() );
49 hiddenAttribute.setDatasize( 0 );
50diff --git a/server/src/storage/datastore.cpp b/server/src/storage/datastore.cpp
51index ae78bab..304f0e8 100644
52--- a/server/src/storage/datastore.cpp
53+++ b/server/src/storage/datastore.cpp
54@@ -183,6 +183,7 @@ bool DataStore::init()
55 Flag::enableCache( true );
56 Resource::enableCache( true );
57 Collection::enableCache( true );
58+ PartType::enableCache( true );
59
60 return true;
61 }
62@@ -1025,7 +1026,8 @@ bool DataStore::unhideAllPimItems()
63 akDebug() << "DataStore::unhideAllPimItems()";
64
65 try {
66- return PartHelper::remove( Part::partTypeIdFullColumnName(), PartTypeHelper::fromName( "ATR", "HIDDEN" ).id() );
67+ return PartHelper::remove( Part::partTypeIdFullColumnName(),
68+ PartType::retrieveByFQName( QLatin1String("ATR"), QLatin1String("HIDDEN") ).id() );
69 } catch ( ... ) {} // we can live with this failing
70
71 return false;
72diff --git a/server/src/storage/entities-header.xsl b/server/src/storage/entities-header.xsl
73index 4966966..d515fd3 100644
74--- a/server/src/storage/entities-header.xsl
75+++ b/server/src/storage/entities-header.xsl
76@@ -133,11 +133,16 @@ class <xsl:value-of select="$className"/> : private Entity
77 <xsl:text>static </xsl:text><xsl:value-of select="$className"/> retrieveById( qint64 id );
78 </xsl:if>
79
80- <xsl:if test="column[@name = 'name']">
81+ <xsl:if test="column[@name = 'name'] and $className != 'PartType'">
82 /** Returns the record with name @p name. */
83 <xsl:text>static </xsl:text><xsl:value-of select="$className"/> retrieveByName( const <xsl:value-of select="column[@name = 'name']/@type"/> &amp;name );
84 </xsl:if>
85
86+ <xsl:if test="column[@name = 'name'] and $className = 'PartType'">
87+ <!-- Special case for PartTypes, which are identified by "NS:NAME" -->
88+ <xsl:text>static PartType retrieveByFQName( const QString &amp;ns, const QString &amp;name );</xsl:text>
89+ </xsl:if>
90+
91 /** Retrieve all records from this table. */
92 static <xsl:value-of select="$className"/>::List retrieveAll();
93 /** Retrieve all records with value @p value in column @p key. */
94diff --git a/server/src/storage/entities-source.xsl b/server/src/storage/entities-source.xsl
95index e398da5..46ef3a6 100644
96--- a/server/src/storage/entities-source.xsl
97+++ b/server/src/storage/entities-source.xsl
98@@ -130,7 +130,15 @@ void <xsl:value-of select="$className"/>::Private::addToCache( const <xsl:value-
99 idCache.insert( entry.id(), entry );
100 </xsl:if>
101 <xsl:if test="column[@name = 'name']">
102+ <xsl:choose>
103+ <xsl:when test="$className = 'PartType'">
104+ <!-- special case for PartType, which is identified as "NS:NAME" -->
105+ nameCache.insert( entry.ns() + QLatin1Char(':') + entry.name(), entry );
106+ </xsl:when>
107+ <xsl:otherwise>
108 nameCache.insert( entry.name(), entry );
109+ </xsl:otherwise>
110+ </xsl:choose>
111 </xsl:if>
112 }
113
114@@ -323,7 +331,7 @@ QVector&lt; <xsl:value-of select="$className"/> &gt; <xsl:value-of select="$clas
115 }
116
117 </xsl:if>
118-<xsl:if test="column[@name = 'name']">
119+<xsl:if test="column[@name = 'name'] and $className != 'PartType'">
120 <xsl:value-of select="$className"/><xsl:text> </xsl:text><xsl:value-of select="$className"/>::retrieveByName( const <xsl:value-of select="column[@name = 'name']/@type"/> &amp;name )
121 {
122 <xsl:call-template name="data-retrieval">
123@@ -333,6 +341,19 @@ QVector&lt; <xsl:value-of select="$className"/> &gt; <xsl:value-of select="$clas
124 }
125 </xsl:if>
126
127+<xsl:if test="column[@name = 'name'] and $className = 'PartType'">
128+<xsl:text>PartType PartType::retrieveByFQName( const QString &amp; ns, const QString &amp; name )</xsl:text>
129+{
130+ const QString fqname = ns + QLatin1Char(':') + name;
131+ <xsl:call-template name="data-retrieval">
132+ <xsl:with-param name="key">ns</xsl:with-param>
133+ <xsl:with-param name="key2">name</xsl:with-param>
134+ <xsl:with-param name="lookupKey">fqname</xsl:with-param>
135+ <xsl:with-param name="cache">nameCache</xsl:with-param>
136+ </xsl:call-template>
137+}
138+</xsl:if>
139+
140 QVector&lt;<xsl:value-of select="$className"/>&gt; <xsl:value-of select="$className"/>::retrieveAll()
141 {
142 QSqlDatabase db = DataStore::self()->database();
143@@ -588,7 +609,15 @@ void <xsl:value-of select="$className"/>::invalidateCache() const
144 Private::idCache.remove( id() );
145 </xsl:if>
146 <xsl:if test="column[@name = 'name']">
147+ <xsl:choose>
148+ <xsl:when test="$className = 'PartType'">
149+ <!-- Special handling for PartType, which is identified as "NS:NAME" -->
150+ Private::nameCache.remove( ns() + QLatin1Char(':') + name() );
151+ </xsl:when>
152+ <xsl:otherwise>
153 Private::nameCache.remove( name() );
154+ </xsl:otherwise>
155+ </xsl:choose>
156 </xsl:if>
157 }
158 }
159diff --git a/server/src/storage/entities.xsl b/server/src/storage/entities.xsl
160index c8fb1fd..2cf96c4 100644
161--- a/server/src/storage/entities.xsl
162+++ b/server/src/storage/entities.xsl
163@@ -169,12 +169,14 @@ set<xsl:value-of select="$methodName"/>( <xsl:call-template name="argument"/> )
164 <!-- data retrieval for a given key field -->
165 <xsl:template name="data-retrieval">
166 <xsl:param name="key"/>
167+<xsl:param name="key2"/>
168+<xsl:param name="lookupKey" select="$key"/>
169 <xsl:param name="cache"/>
170 <xsl:variable name="className"><xsl:value-of select="@name"/></xsl:variable>
171 <xsl:if test="$cache != ''">
172 if ( Private::cacheEnabled ) {
173 QMutexLocker lock(&amp;Private::cacheMutex);
174- QHash&lt;<xsl:value-of select="column[@name = $key]/@type"/>, <xsl:value-of select="$className"/>&gt;::const_iterator it = Private::<xsl:value-of select="$cache"/>.constFind(<xsl:value-of select="$key"/>);
175+ QHash&lt;<xsl:value-of select="column[@name = $key]/@type"/>, <xsl:value-of select="$className"/>&gt;::const_iterator it = Private::<xsl:value-of select="$cache"/>.constFind(<xsl:value-of select="$lookupKey"/>);
176 if ( it != Private::<xsl:value-of select="$cache"/>.constEnd() ) {
177 return it.value();
178 }
179@@ -188,6 +190,9 @@ set<xsl:value-of select="$methodName"/>( <xsl:call-template name="argument"/> )
180 static const QStringList columns = removeEntry(columnNames(), <xsl:value-of select="$key"/>Column());
181 qb.addColumns( columns );
182 qb.addValueCondition( <xsl:value-of select="$key"/>Column(), Query::Equals, <xsl:value-of select="$key"/> );
183+ <xsl:if test="$key2 != ''">
184+ qb.addValueCondition( <xsl:value-of select="$key2"/>Column(), Query::Equals, <xsl:value-of select="$key2"/> );
185+ </xsl:if>
186 if ( !qb.exec() ) {
187 akDebug() &lt;&lt; "Error during selection of record with <xsl:value-of select="$key"/>"
188 &lt;&lt; <xsl:value-of select="$key"/> &lt;&lt; "from table" &lt;&lt; tableName()
189diff --git a/server/src/storage/parttypehelper.cpp b/server/src/storage/parttypehelper.cpp
190index b73dcd5..7654108 100644
191--- a/server/src/storage/parttypehelper.cpp
192+++ b/server/src/storage/parttypehelper.cpp
193@@ -37,7 +37,7 @@ QPair< QString, QString > PartTypeHelper::parseFqName(const QString& fqName)
194 PartType PartTypeHelper::fromFqName(const QString& fqName)
195 {
196 const QPair<QString, QString> p = parseFqName( fqName );
197- return fromName( p.first, p.second );
198+ return PartType::retrieveByFQName(p.first, p.second);
199 }
200
201 PartType PartTypeHelper::fromFqName(const QByteArray& fqName)
202@@ -45,33 +45,6 @@ PartType PartTypeHelper::fromFqName(const QByteArray& fqName)
203 return fromFqName( QLatin1String(fqName) );
204 }
205
206-PartType PartTypeHelper::fromName(const QString& ns, const QString& typeName)
207-{
208- SelectQueryBuilder<PartType> qb;
209- qb.addValueCondition( PartType::nsColumn(), Query::Equals, ns );
210- qb.addValueCondition( PartType::nameColumn(), Query::Equals, typeName );
211- if ( !qb.exec() )
212- throw PartTypeException( "Unable to query part type table." );
213- const PartType::List result = qb.result();
214- if ( result.size() == 1 )
215- return result.first();
216- if ( result.size() > 1 )
217- throw PartTypeException( "Part type uniqueness constraint violation." );
218-
219- // doesn't exist yet, so let's create a new one
220- PartType type;
221- type.setName( typeName );
222- type.setNs( ns );
223- if ( !type.insert() )
224- throw PartTypeException( "Creating a new part type failed." );
225- return type;
226-}
227-
228-PartType PartTypeHelper::fromName(const char* ns, const char* typeName)
229-{
230- return fromName( QLatin1String(ns), QLatin1String(typeName) );
231-}
232-
233 Query::Condition PartTypeHelper::conditionFromFqName(const QString& fqName)
234 {
235 const QPair<QString, QString> p = parseFqName( fqName );
236diff --git a/server/src/storage/parttypehelper.h b/server/src/storage/parttypehelper.h
237index 38cb858..4c4f42f 100644
238--- a/server/src/storage/parttypehelper.h
239+++ b/server/src/storage/parttypehelper.h
240@@ -48,19 +48,6 @@ namespace PartTypeHelper
241 PartType fromFqName( const QByteArray &fqName );
242
243 /**
244- * Retrieve (or create) PartType for the given namespace and type name.
245- * @param ns Namespace
246- * @param typeName Part type name.
247- * @throws PartTypeException
248- */
249- PartType fromName( const QString &ns, const QString &typeName );
250-
251- /**
252- * Convenience overload of the above.
253- */
254- PartType fromName( const char *ns, const char *typeName );
255-
256- /**
257 * Returns a query condition that matches the given part.
258 * @param fqName fully-qualified part type name
259 * @throws PartTypeException
260--
2612.1.0
262
This page took 0.106736 seconds and 4 git commands to generate.