[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/plasma/private
From:       Marco Martin <notmart () gmail ! com>
Date:       2011-01-07 10:51:30
Message-ID: 20110107105130.0794CAC8B0 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1212521 by mart:

use a single database connection per thread, anchieve that with a static \
QThreadStorage each thread data will have a refcounted database instance


 M  +62 -22    storage.cpp  
 M  +3 -1      storage_p.h  


--- trunk/KDE/kdelibs/plasma/private/storage.cpp #1212520:1212521
@@ -25,6 +25,7 @@
 #include <QSqlError>
 #include <QSqlQuery>
 #include <QSqlRecord>
+#include <QThreadStorage>
 
 //KDE
 #include <kdebug.h>
@@ -35,8 +36,47 @@
 #include "dataengine.h"
 #include "abstractrunner.h"
 
-static uint connectionId = 0;
 
+class RefCountedDatabase
+{
+public:
+    void ref()
+    {
+        if (m_ref == 0) {
+            m_db = QSqlDatabase::addDatabase("QSQLITE", \
QString("plasma-storage-%1").arg((int)this)); +            \
m_db.setDatabaseName(KStandardDirs::locateLocal("appdata", "plasma-storage.db")); +   \
} +        //Q_ASSERT(db.isValid());
+        m_ref.ref();
+    }
+
+    bool deref()
+    {
+        //kill the database if the last one in use
+        bool last = !m_ref.deref();
+        if (last) {
+            m_db.close();
+            QString name = m_db.connectionName();
+            m_db = QSqlDatabase();
+            QSqlDatabase::removeDatabase(name);
+        }
+        return !last;
+    }
+
+    inline QSqlDatabase *database()
+    {
+        return &m_db;
+    }
+
+private:
+    QSqlDatabase m_db;
+    QAtomicInt m_ref;
+};
+
+static QThreadStorage<RefCountedDatabase *> s_databasePool;
+
+
+
 //Storage Job implentation
 StorageJob::StorageJob(const QString& destination,
                        const QString& operation,
@@ -45,13 +85,18 @@
             : ServiceJob(destination, operation, parameters, parent),
               m_clientName(destination)
 {
-    m_db = new QSqlDatabase(QSqlDatabase::addDatabase("QSQLITE", \
                QString("plasma-storage-%1").arg(++connectionId)));
-    m_db->setDatabaseName(KStandardDirs::locateLocal("appdata", \
"plasma-storage.db")); +    m_rdb = s_databasePool.localData();
+    if (m_rdb == 0) {
+        s_databasePool.setLocalData(new RefCountedDatabase);
+        m_rdb = s_databasePool.localData();
+    }
 
-    if (!m_db->open()) {
-        kWarning() << "Unable to open the plasma storage cache database: " << \
                m_db->lastError();
-    } else if (!m_db->tables().contains(m_clientName)) {
-        QSqlQuery query(*m_db);
+    m_rdb->ref();
+
+    if (!m_rdb->database()->open()) {
+        kWarning() << "Unable to open the plasma storage cache database: " << \
m_rdb->database()->lastError(); +    } else if \
(!m_rdb->database()->tables().contains(m_clientName)) { +        QSqlQuery \
                query(*m_rdb->database());
         //bindValue doesn't seem to be able to replace stuff in create table
         query.prepare(QString("create table ")+m_clientName+" (valueGroup \
varchar(256), id varchar(256), data clob, creationTime datetime, accessTime datetime, \
primary key (valueGroup, id))");  query.exec();
@@ -60,12 +105,14 @@
 
 StorageJob::~StorageJob()
 {
-    delete m_db;
+    if (!m_rdb->deref()) {
+        s_databasePool.setLocalData(0);
 }
+}
 
 void StorageJob::start()
 {
-    if (!m_db->isOpen()) {
+    if (!m_rdb->database()->isOpen()) {
         return;
     }
 
@@ -78,7 +125,7 @@
 
 
     if (operationName() == "save") {
-      QSqlQuery query(*m_db);
+      QSqlQuery query(*m_rdb->database());
       query.prepare("delete from "+m_clientName+" where valueGroup=:valueGroup and \
id = :id");  query.bindValue(":valueGroup", valueGroup);
       query.bindValue(":id", params["key"].toString());
@@ -87,12 +134,11 @@
       query.prepare("insert into "+m_clientName+" values(:valueGroup, :id, \
:datavalue, date('now'), date('now'))");  query.bindValue(":id", \
params["key"].toString());  query.bindValue(":valueGroup", valueGroup);
-      query.bindValue(":datavalue", params["data"]);
+      query.bindValue(":datavalue", params["data"].toString());
       const bool success = query.exec();
       setResult(success);
-
     } else if (operationName() == "retrieve") {
-        QSqlQuery query(*m_db);
+        QSqlQuery query(*m_rdb->database());
 
         //a bit redundant but should be the faster way with less string \
concatenation as possible  if (params["key"].toString().isEmpty()) {
@@ -131,7 +177,7 @@
         }
 
     } else if (operationName() == "delete") {
-        QSqlQuery query(*m_db);
+        QSqlQuery query(*m_rdb->database());
 
         if (params["key"].toString().isEmpty()) {
             query.prepare("delete from "+m_clientName+" where \
valueGroup=:valueGroup"); @@ -146,7 +192,7 @@
         setResult(success);
 
     } else if (operationName() == "expire") {
-        QSqlQuery query(*m_db);
+        QSqlQuery query(*m_rdb->database());
         if (valueGroup.isEmpty()) {
             query.prepare("delete from "+m_clientName+" where accessTime < :date");
             QDateTime time(QDateTime::currentDateTime());
@@ -166,13 +212,7 @@
     } else {
         setError(true);
     }
-    //TODO: use a single shared db per thread
-    m_db->commit();
-    m_db->close();
-    QString name = m_db->connectionName();
-    delete m_db;
-    m_db = 0;
-    QSqlDatabase::removeDatabase(name);
+    m_rdb->database()->commit();
 }
 
 Plasma::ServiceJob* Storage::createJob(const QString &operation, QMap<QString, \
                QVariant> &parameters)
--- trunk/KDE/kdelibs/plasma/private/storage_p.h #1212520:1212521
@@ -28,6 +28,8 @@
 #include <plasma/service.h>
 #include <plasma/servicejob.h>
 
+class RefCountedDatabase;
+
 //Begin StorageJob
 class StorageJob : public Plasma::ServiceJob
 {
@@ -40,7 +42,7 @@
     ~StorageJob();
     void start();
 private:
-    QSqlDatabase *m_db;
+    RefCountedDatabase *m_rdb;
     QString m_clientName;
 };
 //End StorageJob


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic