use Floyd cycle detection
This commit is contained in:
parent
21cf68dbd2
commit
55a6095138
@ -193,7 +193,8 @@ void Package::setFallbackPackage(const Plasma::Package &package)
|
||||
{
|
||||
if ((d->fallbackPackage && d->fallbackPackage->path() == package.path() && d->fallbackPackage->metadata() == package.metadata()) ||
|
||||
//can't be fallback of itself
|
||||
(package.path() == path() && package.metadata() == metadata())) {
|
||||
(package.path() == path() && package.metadata() == metadata()) ||
|
||||
d->hasCycle(package)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -908,4 +909,27 @@ QString PackagePrivate::fallbackFilePath(const char *key, const QString &filenam
|
||||
}
|
||||
}
|
||||
|
||||
bool PackagePrivate::hasCycle(const Plasma::Package &package)
|
||||
{
|
||||
if (!package.d->fallbackPackage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//This is the Floyd cycle detection algorithm
|
||||
//http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
|
||||
const Plasma::Package *slowPackage = &package;
|
||||
const Plasma::Package *fastPackage = &package;
|
||||
|
||||
while (fastPackage && fastPackage->d->fallbackPackage) {
|
||||
//consider two packages the same if they have the same metadata
|
||||
if ((fastPackage->d->fallbackPackage->metadata().isValid() && fastPackage->d->fallbackPackage->metadata() == slowPackage->metadata()) ||
|
||||
(fastPackage->d->fallbackPackage->d->fallbackPackage->metadata().isValid() && fastPackage->d->fallbackPackage->d->fallbackPackage->metadata() == slowPackage->metadata())) {
|
||||
return true;
|
||||
}
|
||||
fastPackage = fastPackage->d->fallbackPackage->d->fallbackPackage;
|
||||
slowPackage = slowPackage->d->fallbackPackage;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // Namespace
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
QString unpack(const QString &filePath);
|
||||
void updateHash(const QString &basePath, const QString &subPath, const QDir &dir, QCryptographicHash &hash);
|
||||
QString fallbackFilePath(const char *key, const QString &filename = QString()) const;
|
||||
bool hasCycle(const Plasma::Package &package);
|
||||
|
||||
QWeakPointer<PackageStructure> structure;
|
||||
QString path;
|
||||
|
Loading…
Reference in New Issue
Block a user