// own process. Therefore nothing needs to be done here!
#else
// Use the path to figure out whether it was our own change
- const auto maxNotificationDelay = 15 * 1000;
- qint64 time = _engine->timeSinceFileTouched(path);
- if (time != -1 && time < maxNotificationDelay) {
+ if (_engine->wasFileTouched(path)) {
+ qCDebug(lcFolder) << "Changed path was touched by SyncEngine, ignoring:" << path;
return;
}
#endif
Q_LOGGING_CATEGORY(lcEngine, "sync.engine", QtInfoMsg)
+static const int s_touchedFilesMaxAgeMs = 15 * 1000;
bool SyncEngine::s_anySyncRunning = false;
qint64 SyncEngine::minimumFileAgeForUpload = 2000;
void SyncEngine::slotAddTouchedFile(const QString &fn)
{
+ QElapsedTimer now;
+ now.start();
QString file = QDir::cleanPath(fn);
- QElapsedTimer timer;
- timer.start();
+ // Iterate from the oldest and remove anything older than 15 seconds.
+ while (true) {
+ auto first = _touchedFiles.begin();
+ if (first == _touchedFiles.end())
+ break;
+ // Compare to our new QElapsedTimer instead of using elapsed().
+ // This avoids querying the current time from the OS for every loop.
+ if (now.msecsSinceReference() - first.key().msecsSinceReference() <= s_touchedFilesMaxAgeMs) {
+ // We found the first path younger than 15 second, keep the rest.
+ break;
+ }
- _touchedFiles.insert(file, timer);
+ _touchedFiles.erase(first);
+ }
+
+ // This should be the largest QElapsedTimer yet, use constEnd() as hint.
+ _touchedFiles.insert(_touchedFiles.constEnd(), now, file);
}
void SyncEngine::slotClearTouchedFiles()
_touchedFiles.clear();
}
-qint64 SyncEngine::timeSinceFileTouched(const QString &fn) const
+bool SyncEngine::wasFileTouched(const QString &fn) const
{
- if (!_touchedFiles.contains(fn)) {
- return -1;
+ // Start from the end (most recent) and look for our path. Check the time just in case.
+ auto begin = _touchedFiles.constBegin();
+ for (auto it = _touchedFiles.constEnd(); it != begin; --it) {
+ if ((it-1).value() == fn)
+ return (it-1).key().elapsed() <= s_touchedFilesMaxAgeMs;
}
-
- return _touchedFiles[fn].elapsed();
+ return false;
}
AccountPtr SyncEngine::account() const
/* Returns whether another sync is needed to complete the sync */
AnotherSyncNeeded isAnotherSyncNeeded() { return _anotherSyncNeeded; }
- /** Get the ms since a file was touched, or -1 if it wasn't.
- *
- * Thread-safe.
- */
- qint64 timeSinceFileTouched(const QString &fn) const;
+ bool wasFileTouched(const QString &fn) const;
AccountPtr account() const;
SyncJournalDb *journal() const { return _journal; }
AnotherSyncNeeded _anotherSyncNeeded;
/** Stores the time since a job touched a file. */
- QHash<QString, QElapsedTimer> _touchedFiles;
+ QMultiMap<QElapsedTimer, QString> _touchedFiles;
/** For clearing the _touchedFiles variable after sync finished */
QTimer _clearTouchedFilesTimer;