]> git.pld-linux.org Git - packages/akonadi.git/blob - 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
1 From 215b188d891d5236fe94131d176d7ddc3ae02d5d Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= <dvratil@redhat.com>
3 Date: Fri, 5 Dec 2014 17:12:28 +0100
4 Subject: [PATCH 20/30] Avoid ridiculous amount of SQL queries by caching
5  PartTypes
6
7 PartTypes are identified by their FQ name, which is in form NAMESPACE:NAME,
8 where namespace and name are stored in individual columns. For this reason
9 the standard ::retrieveByName() and name cache generated from entities.xslt
10 does not work. This patch adds special handling for PartType table, so that
11 a special PartType::retrieveByFQName() method as well as PartType name cache
12 handling are generated during the XSL Transformation, allowing us to cache
13 all the PartTypes.
14
15 This reduces the amount of SQL queries by at least two for each single AKAPPEND,
16 MERGE, STORE and FETCH command, providing a nice performance boost during
17 sync.
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
28 diff --git a/server/src/handler/append.cpp b/server/src/handler/append.cpp
29 index 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 );
50 diff --git a/server/src/storage/datastore.cpp b/server/src/storage/datastore.cpp
51 index 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;
72 diff --git a/server/src/storage/entities-header.xsl b/server/src/storage/entities-header.xsl
73 index 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. */
94 diff --git a/server/src/storage/entities-source.xsl b/server/src/storage/entities-source.xsl
95 index 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  }
159 diff --git a/server/src/storage/entities.xsl b/server/src/storage/entities.xsl
160 index 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()
189 diff --git a/server/src/storage/parttypehelper.cpp b/server/src/storage/parttypehelper.cpp
190 index 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 );
236 diff --git a/server/src/storage/parttypehelper.h b/server/src/storage/parttypehelper.h
237 index 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 -- 
261 2.1.0
262
This page took 0.088448 seconds and 3 git commands to generate.