summaryrefslogtreecommitdiffstats
path: root/archivemodel.cpp
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2013-06-22 15:08:14 +0200
committerArno <am@disconnect.de>2013-06-22 15:08:14 +0200
commit77b6cc27c7c2a97b0759332cdfa382d4b32b8749 (patch)
tree37684e95c803cdec76b976d4b0c4f04ea75f19dc /archivemodel.cpp
parent1627d5fb197cb7d28191264e98b93dc55d92ed1b (diff)
downloadSheMov-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.cpp104
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 &regex, 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();