diff options
author | Arno <am@disconnect.de> | 2013-06-22 15:08:14 +0200 |
---|---|---|
committer | Arno <am@disconnect.de> | 2013-06-22 15:08:14 +0200 |
commit | 77b6cc27c7c2a97b0759332cdfa382d4b32b8749 (patch) | |
tree | 37684e95c803cdec76b976d4b0c4f04ea75f19dc /archivemodel.cpp | |
parent | 1627d5fb197cb7d28191264e98b93dc55d92ed1b (diff) | |
download | SheMov-77b6cc27c7c2a97b0759332cdfa382d4b32b8749.tar.gz SheMov-77b6cc27c7c2a97b0759332cdfa382d4b32b8749.tar.bz2 SheMov-77b6cc27c7c2a97b0759332cdfa382d4b32b8749.zip |
Archive Cache
Create a caches of database archive views. Esp. gathering data for
actors takes a long time, and I don't see how to optimize the queries.
So write them to a QDataStream. It was much more difficult that it
sounds. Once again I was lost in recursion. Did I mention that I hate
recursion?
The solution:
When writing use the address of the SMTreeItem cast to qint64 as unique
key. On reading build a hash with the address as key and use it to find
the parent of the next item.
I hope that makes sense...
Diffstat (limited to 'archivemodel.cpp')
-rw-r--r-- | archivemodel.cpp | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/archivemodel.cpp b/archivemodel.cpp index b83718c..c169b4d 100644 --- a/archivemodel.cpp +++ b/archivemodel.cpp @@ -7,6 +7,8 @@ #include <QSqlError> #include <QSqlQuery> +#include <QFile> +#include <QSettings> #include "smtreeitem.h" #include "archivemodel.h" @@ -193,10 +195,15 @@ QModelIndexList ArchiveModel::pathToIndex(const QStringList &path) const { void ArchiveModel::setOrder(int order) { mOrder = order; - SmTreeItem *rootItem = new SmTreeItem(NumFields); - mCollector->populate(mOrder, rootItem); - if(!mCollector->isRunning()){ - mCollector->start(); + SmTreeItem *rootItem = readCache(mOrder); + if(rootItem){ + setRoot(rootItem); + }else{ + rootItem = new SmTreeItem(NumFields); + mCollector->populate(mOrder, rootItem); + if(!mCollector->isRunning()){ + mCollector->start(); + } } } @@ -212,6 +219,7 @@ void ArchiveModel::refresh(){ void ArchiveModel::collectorFinished(){ SmTreeItem *item = mCollector->rootItem(); setRoot(item); + writeCache(mOrder); } bool ArchiveModel::checkParents(const SmTreeItem *item, const QRegExp ®ex, int column) const { @@ -232,6 +240,94 @@ void ArchiveModel::emitDatabaseError(const QSqlError &e){ emit databaseError(errormsg); } +void ArchiveModel::writeCache(int o){ + QFile cache(cacheFile(o)); + cache.open(QIODevice::WriteOnly); + QDataStream stream(&cache); + // write root id, no need to write data + // it's invalid anyway, we just need it as an anchor + stream << (qint64)root(); + for(int i = 0; i < root()->childCount(); ++i){ + writeRecursive(root()->child(i), stream); + } +} + +void ArchiveModel::writeRecursive(SmTreeItem *start, QDataStream &stream){ + if(start->childCount()){ + stream << (quint64)start->parent() << (qint64)start; + writeItem(start, stream); + for(int i = 0; i < start->childCount(); ++i){ + writeRecursive(start->child(i), stream); + } + }else{ + stream << (qint64)start->parent() << (qint64)start; + writeItem(start, stream); + } +} + +void ArchiveModel::writeItem(SmTreeItem *item, QDataStream &stream){ + for(int i = 0; i < NumFields; ++i){ + stream << item->data(i); + } +} + +SmTreeItem *ArchiveModel::readCache(int o){ + QFile cache(cacheFile(o)); + if(!cache.exists() || !cache.size()){ + return 0; + } + cache.open(QIODevice::ReadOnly); + QDataStream stream(&cache); + QHash<qint64, SmTreeItem*> idHash; + qint64 rootId; + stream >> rootId; + SmTreeItem *rootItem = new SmTreeItem(NumFields); + idHash.insert(rootId, rootItem); + qint64 parentId = 0; + qint64 myId = 0; + while(!stream.atEnd()){ + stream >> parentId >> myId; + SmTreeItem *curItem = readItem(stream); + SmTreeItem *parentItem = idHash.value(parentId, 0); + Q_ASSERT(parentItem); + curItem->setParent(parentItem); + parentItem->appendChild(curItem); + idHash.insert(myId, curItem); + } + return rootItem; +} + +SmTreeItem *ArchiveModel::readItem(QDataStream &stream) const{ + QList<QVariant> data; + QVariant cur; + for(int i = 0; i < NumFields; ++i){ + stream >> cur; + data << cur; + } + SmTreeItem *retval = new SmTreeItem(data); + return retval; +} + +const QString ArchiveModel::cacheFile(int o) const{ + QSettings s; + QString archive = s.value("paths/archivedir").toString(); + QString cacheFile = QString("%1/.archivecache/").arg(archive); + switch(o){ + case Actor: + cacheFile.append("actors.cache"); + break; + case Genre: + cacheFile.append("genre.cache"); + break; + case SeriesName: + cacheFile.append("seriesname.cache"); + break; + default: + return QString(); + } + return cacheFile; +} + ArchiveCollector::ArchiveCollector(int numFields, QObject *parent) : QThread(parent), mNumFields(numFields) { mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "archivedb"); mDb.open(); |