QFileSystemWatcherEngines: port some Java-style iterators to ranged-for
Java-style iterators are scheduled to be deprecated. The general pattern used in the patch is that instead of copying an input list, then iterating over the copy with some calls to it.remove() (which leads to quadratic-complexity loops), we simply copy conditionally (a la remove_copy_if instead of remove_if). To make clearer what's going on, rename the outgoing list to 'unhandled'. To avoid having to touch too much of the loops' structure, which sometimes is quite convoluted, use qScopeGuard to do the append to 'unhandled', unless the original code removed the element. Saves a surprising almost 5KiB in text size on GCC 9.1 optimized AMD64 Linux builds. Change-Id: Ifd861de9aa48d66b420858606998dd08a8401e03 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
parent
4e026a2076
commit
b03385f9cf
|
|
@ -46,6 +46,7 @@
|
|||
#include <qdebug.h>
|
||||
#include <qfile.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qscopeguard.h>
|
||||
#include <qsocketnotifier.h>
|
||||
#include <qvarlengtharray.h>
|
||||
|
||||
|
|
@ -268,12 +269,11 @@ QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
QFileInfo fi(path);
|
||||
bool isDir = fi.isDir();
|
||||
auto sg = qScopeGuard([&]{ unhandled.push_back(path); });
|
||||
if (isDir) {
|
||||
if (directories->contains(path))
|
||||
continue;
|
||||
|
|
@ -305,7 +305,7 @@ QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
continue;
|
||||
}
|
||||
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
|
||||
int id = isDir ? -wd : wd;
|
||||
if (id < 0) {
|
||||
|
|
@ -318,19 +318,19 @@ QStringList QInotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
idToPath.insert(id, path);
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &paths,
|
||||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
int id = pathToID.take(path);
|
||||
|
||||
auto sg = qScopeGuard([&]{ unhandled.push_back(path); });
|
||||
|
||||
// Multiple paths could be associated to the same watch descriptor
|
||||
// when a file is moved and added with the new name.
|
||||
// So we should find and delete the correct one by using
|
||||
|
|
@ -349,7 +349,8 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
inotify_rm_watch(inotifyFd, wd);
|
||||
}
|
||||
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
|
||||
if (id < 0) {
|
||||
directories->removeAll(path);
|
||||
} else {
|
||||
|
|
@ -357,7 +358,7 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
void QInotifyFileSystemWatcherEngine::readFromInotify()
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include <qdebug.h>
|
||||
#include <qfile.h>
|
||||
#include <qscopeguard.h>
|
||||
#include <qsocketnotifier.h>
|
||||
#include <qvarlengtharray.h>
|
||||
|
||||
|
|
@ -94,10 +95,9 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
auto sg = qScopeGuard([&]{unhandled.push_back(path);});
|
||||
int fd;
|
||||
#if defined(O_EVTONLY)
|
||||
fd = qt_safe_open(QFile::encodeName(path), O_EVTONLY);
|
||||
|
|
@ -149,7 +149,8 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
continue;
|
||||
}
|
||||
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
|
||||
if (id < 0) {
|
||||
DEBUG() << "QKqueueFileSystemWatcherEngine: added directory path" << path;
|
||||
directories->append(path);
|
||||
|
|
@ -162,20 +163,19 @@ QStringList QKqueueFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
idToPath.insert(id, path);
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths,
|
||||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
if (pathToID.isEmpty())
|
||||
return p;
|
||||
return paths;
|
||||
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
auto sg = qScopeGuard([&]{unhandled.push_back(path);});
|
||||
int id = pathToID.take(path);
|
||||
QString x = idToPath.take(id);
|
||||
if (x.isEmpty() || x != path)
|
||||
|
|
@ -183,14 +183,15 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
|
|||
|
||||
::close(id < 0 ? -id : id);
|
||||
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
|
||||
if (id < 0)
|
||||
directories->removeAll(path);
|
||||
else
|
||||
files->removeAll(path);
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
void QKqueueFileSystemWatcherEngine::readFromKqueue()
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qfilesystemwatcher_polling_p.h"
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -53,10 +54,9 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
auto sg = qScopeGuard([&]{ unhandled.push_back(path); });
|
||||
QFileInfo fi(path);
|
||||
if (!fi.exists())
|
||||
continue;
|
||||
|
|
@ -73,7 +73,7 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
files->append(path);
|
||||
this->files.insert(path, fi);
|
||||
}
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
}
|
||||
|
||||
if ((!this->files.isEmpty() ||
|
||||
|
|
@ -82,23 +82,21 @@ QStringList QPollingFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
timer.start(PollingInterval);
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &paths,
|
||||
QStringList *files,
|
||||
QStringList *directories)
|
||||
{
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
if (this->directories.remove(path)) {
|
||||
directories->removeAll(path);
|
||||
it.remove();
|
||||
} else if (this->files.remove(path)) {
|
||||
files->removeAll(path);
|
||||
it.remove();
|
||||
} else {
|
||||
unhandled.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +105,7 @@ QStringList QPollingFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
timer.stop();
|
||||
}
|
||||
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
void QPollingFileSystemWatcherEngine::timeout()
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <qfileinfo.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qset.h>
|
||||
#include <qscopeguard.h>
|
||||
#include <qdatetime.h>
|
||||
#include <qdir.h>
|
||||
#include <qtextstream.h>
|
||||
|
|
@ -377,10 +378,9 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
QStringList *directories)
|
||||
{
|
||||
DEBUG() << "Adding" << paths.count() << "to existing" << (files->count() + directories->count()) << "watchers";
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
auto sg = qScopeGuard([&] { unhandled.push_back(path); });
|
||||
QString normalPath = path;
|
||||
if ((normalPath.endsWith(QLatin1Char('/')) && !normalPath.endsWith(QLatin1String(":/")))
|
||||
|| (normalPath.endsWith(QLatin1Char('\\')) && !normalPath.endsWith(QLatin1String(":\\")))) {
|
||||
|
|
@ -463,7 +463,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
else
|
||||
files->append(path);
|
||||
}
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
thread->wakeup();
|
||||
break;
|
||||
}
|
||||
|
|
@ -493,7 +493,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
else
|
||||
files->append(path);
|
||||
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
found = true;
|
||||
thread->wakeup();
|
||||
break;
|
||||
|
|
@ -519,7 +519,7 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
thread->msg = '@';
|
||||
thread->start();
|
||||
threads.append(thread);
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -527,12 +527,12 @@ QStringList QWindowsFileSystemWatcherEngine::addPaths(const QStringList &paths,
|
|||
#ifndef Q_OS_WINRT
|
||||
if (Q_LIKELY(m_driveListener)) {
|
||||
for (const QString &path : paths) {
|
||||
if (!p.contains(path))
|
||||
if (!unhandled.contains(path))
|
||||
m_driveListener->addPath(path);
|
||||
}
|
||||
}
|
||||
#endif // !Q_OS_WINRT
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &paths,
|
||||
|
|
@ -540,10 +540,9 @@ QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
QStringList *directories)
|
||||
{
|
||||
DEBUG() << "removePaths" << paths;
|
||||
QStringList p = paths;
|
||||
QMutableListIterator<QString> it(p);
|
||||
while (it.hasNext()) {
|
||||
QString path = it.next();
|
||||
QStringList unhandled;
|
||||
for (const QString &path : paths) {
|
||||
auto sg = qScopeGuard([&] { unhandled.push_back(path); });
|
||||
QString normalPath = path;
|
||||
if (normalPath.endsWith(QLatin1Char('/')) || normalPath.endsWith(QLatin1Char('\\')))
|
||||
normalPath.chop(1);
|
||||
|
|
@ -572,7 +571,7 @@ QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
// ###
|
||||
files->removeAll(path);
|
||||
directories->removeAll(path);
|
||||
it.remove();
|
||||
sg.dismiss();
|
||||
|
||||
if (h.isEmpty()) {
|
||||
DEBUG() << "Closing handle" << handle.handle;
|
||||
|
|
@ -613,7 +612,7 @@ QStringList QWindowsFileSystemWatcherEngine::removePaths(const QStringList &path
|
|||
}
|
||||
|
||||
threads.removeAll(0);
|
||||
return p;
|
||||
return unhandled;
|
||||
}
|
||||
|
||||
///////////
|
||||
|
|
|
|||
Loading…
Reference in New Issue