Commit cb1ad6cc authored by Lisa's avatar Lisa
Browse files

Concurrent function added to compute the list of orphaned packages.

parent cf125bd1
...@@ -58,6 +58,62 @@ struct ConcurrentPackageQuery ...@@ -58,6 +58,62 @@ struct ConcurrentPackageQuery
QString m_sql; QString m_sql;
}; };
struct ConcurrentOrphanQuery
{
ConcurrentOrphanQuery()
{}
typedef QList< Package* > result_type;
/* Computes the list of orphan packages */
QList< Package* > operator()()
{
QHash< QString, Package* > allPackages;
QStringList toBeRemoved;
foreach (Package* pkg, Backend::instance()->localDatabase()->packages()) {
allPackages[ pkg->name() ] = pkg;
}
foreach (Package* pkg, allPackages.values()) {
if (pkg->installReason() == Package::ExplicitlyInstalledReason) {
toBeRemoved += depsToRemove(pkg);
}
}
/* I do this separately to avoid issues in the foreach loop */
foreach (const QString& p, toBeRemoved) {
allPackages.remove(p);
}
return allPackages.values();
}
/*
* TODO: there are a lot of repetitions in the dep list returned here:
* maybe we should use a QSet instead of a QList? That would slow down the inserting but speed up the final removing.
*/
QStringList depsToRemove(Package* root)
{
QStringList deps;
Package::List stack;
stack.push_front(root);
deps.append( root->name() );
while (!stack.isEmpty()) {
Package* current = stack.takeFirst();
foreach (Package* dep, current->computeDependencies()) {
deps.append( dep->name() );
stack.append(dep);
}
}
return deps;
}
};
struct ConcurrentGroupQuery struct ConcurrentGroupQuery
{ {
ConcurrentGroupQuery(QString const& sql) ConcurrentGroupQuery(QString const& sql)
...@@ -201,15 +257,39 @@ void BackendPrivate::packageQueryFinished() ...@@ -201,15 +257,39 @@ void BackendPrivate::packageQueryFinished()
return; return;
} }
QList<Package*> retlist;
// Create the result
QFuture< QList< Package* > > const& future = queryPackageFuturePool[uuid]->future(); QFuture< QList< Package* > > const& future = queryPackageFuturePool[uuid]->future();
for (QFuture< QList< Package* > >::const_iterator i = future.constBegin(); i != future.constEnd(); ++i) { sender()->deleteLater();
retlist << *i;
QList< Package* > result;
foreach (QList< Package* > res, future.results()) {
result += res;
} }
emit q->queryPackagesCompleted(uuid, result);
}
void BackendPrivate::orphanQueryFinished()
{
Q_Q(Backend);
QUuid uuid = QUuid( sender()->property("__Akabei_Query_Uuid").toString() );
if (!orphanPackageFuturePool.contains(uuid)) {
qWarning() << "No such UUID registered!";
emit q->queryOrphansCompleted(uuid, QList< Package* >());
sender()->deleteLater();
return;
}
QFuture< QList< Package* > > const& future = orphanPackageFuturePool[uuid]->future();
sender()->deleteLater(); sender()->deleteLater();
emit q->queryPackagesCompleted(uuid, retlist);
QList< Package* > result;
foreach (QList< Package* > res, future.results()) {
result += res;
}
emit q->queryOrphansCompleted(uuid, result);
} }
void BackendPrivate::groupQueryFinished() void BackendPrivate::groupQueryFinished()
...@@ -223,14 +303,14 @@ void BackendPrivate::groupQueryFinished() ...@@ -223,14 +303,14 @@ void BackendPrivate::groupQueryFinished()
return; return;
} }
QList<Group*> retlist;
// Create the result
QFuture< QList< Group* > > const& future = queryGroupFuturePool[uuid]->future(); QFuture< QList< Group* > > const& future = queryGroupFuturePool[uuid]->future();
for (QFuture< QList< Group* > >::const_iterator i = future.constBegin(); i != future.constEnd(); ++i) { QList< Group* > result;
retlist << *i;
foreach (QList< Group* > res, future.results()) {
result += res;
} }
emit q->queryGroupsCompleted(uuid, retlist); emit q->queryGroupsCompleted(uuid, result);
} }
void BackendPrivate::__k__lockGranted() void BackendPrivate::__k__lockGranted()
...@@ -461,6 +541,22 @@ QUuid Backend::queryPackages(const QString& sql) ...@@ -461,6 +541,22 @@ QUuid Backend::queryPackages(const QString& sql)
return uuid; return uuid;
} }
QUuid Backend::orphanPackages()
{
Q_D(Backend);
QUuid uuid = QUuid::createUuid();
QFutureWatcher< QList< Package* > >* watcher = new QFutureWatcher< QList< Package* > >();
watcher->setProperty("__Akabei_Query_Uuid", uuid.toString());
connect(watcher, SIGNAL(finished()), d, SLOT(orphanQueryFinished()));
d->orphanPackageFuturePool.insert(uuid, watcher);
QFuture< QList< Package* > > future = QtConcurrent::run( ConcurrentOrphanQuery() );
watcher->setFuture(future);
return uuid;
}
QUuid Backend::searchGroups(const QString& token) QUuid Backend::searchGroups(const QString& token)
{ {
QString sql = "SELECT * FROM groups WHERE name LIKE \"%" + token + "%\" OR description LIKE \"%" + token + "%\""; QString sql = "SELECT * FROM groups WHERE name LIKE \"%" + token + "%\" OR description LIKE \"%" + token + "%\"";
......
...@@ -151,6 +151,13 @@ class AKABEICORESHARED_EXPORT Backend : public QObject ...@@ -151,6 +151,13 @@ class AKABEICORESHARED_EXPORT Backend : public QObject
*/ */
QUuid queryPackages(const QString &sql); QUuid queryPackages(const QString &sql);
/**
* Computes the list of orphaned packages in the local database and emits queryOrphansCompleted()
* @returns the \c QUuid associated with the operation.
* @see queryOrphansCompleted()
*/
QUuid orphanPackages();
/** /**
* Performs a simple SQL-Query on all databases and emits queryPackagesCompleted() * Performs a simple SQL-Query on all databases and emits queryPackagesCompleted()
* @returns the \c QUuid associated with the query * @returns the \c QUuid associated with the query
...@@ -208,6 +215,14 @@ class AKABEICORESHARED_EXPORT Backend : public QObject ...@@ -208,6 +215,14 @@ class AKABEICORESHARED_EXPORT Backend : public QObject
* @param result the result of the query, in this case a list of Akabei::Packages * @param result the result of the query, in this case a list of Akabei::Packages
*/ */
void queryPackagesCompleted(const QUuid &id, const QList<Akabei::Package*> &result); void queryPackagesCompleted(const QUuid &id, const QList<Akabei::Package*> &result);
/**
* Computation of orphans packages completed.
* @param id the \c QUuid associated with the operation
* @param result the resulted Package list.
*/
void queryOrphansCompleted(const QUuid &id, const QList<Akabei::Package*> &result);
/** /**
* A group query got completed. * A group query got completed.
* @param id the \c QUuid associated with the query * @param id the \c QUuid associated with the query
......
...@@ -82,6 +82,7 @@ class BackendPrivate : public QObject ...@@ -82,6 +82,7 @@ class BackendPrivate : public QObject
QFutureWatcher< QHash< QString, Database* > > *initializationWatcher; QFutureWatcher< QHash< QString, Database* > > *initializationWatcher;
QHash< QUuid, QFutureWatcher< QList < Package* > >* > queryPackageFuturePool; QHash< QUuid, QFutureWatcher< QList < Package* > >* > queryPackageFuturePool;
QHash< QUuid, QFutureWatcher< QList < Group* > >* > queryGroupFuturePool; QHash< QUuid, QFutureWatcher< QList < Group* > >* > queryGroupFuturePool;
QHash< QUuid, QFutureWatcher< QList < Package* > >* > orphanPackageFuturePool;
OperationRunner *runner; OperationRunner *runner;
...@@ -100,6 +101,7 @@ class BackendPrivate : public QObject ...@@ -100,6 +101,7 @@ class BackendPrivate : public QObject
public slots: public slots:
void packageQueryFinished(); void packageQueryFinished();
void groupQueryFinished(); void groupQueryFinished();
void orphanQueryFinished();
}; };
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment