Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/csync/csync.cpp3
-rw-r--r--src/csync/csync_private.h10
-rw-r--r--src/csync/csync_update.cpp15
-rw-r--r--src/gui/issueswidget.cpp5
-rw-r--r--src/libsync/syncengine.cpp36
-rw-r--r--src/libsync/syncengine.h12
-rw-r--r--test/testsyncengine.cpp32
7 files changed, 75 insertions, 38 deletions
diff --git a/src/csync/csync.cpp b/src/csync/csync.cpp
index 992e60f21..4474ef0e9 100644
--- a/src/csync/csync.cpp
+++ b/src/csync/csync.cpp
@@ -310,9 +310,6 @@ int csync_s::reinitialize() {
renames.folder_renamed_from.clear();
renames.folder_renamed_to.clear();
- local_discovery_style = LocalDiscoveryStyle::FilesystemOnly;
- locally_touched_dirs.clear();
-
status = CSYNC_STATUS_INIT;
SAFE_FREE(error_string);
diff --git a/src/csync/csync_private.h b/src/csync/csync_private.h
index f73a1b2d5..1e394e4dc 100644
--- a/src/csync/csync_private.h
+++ b/src/csync/csync_private.h
@@ -190,15 +190,7 @@ struct OCSYNC_EXPORT csync_s {
*/
bool read_remote_from_db = false;
- LocalDiscoveryStyle local_discovery_style = LocalDiscoveryStyle::FilesystemOnly;
-
- /**
- * List of folder-relative directory paths that should be scanned on the
- * filesystem if the local_discovery_style suggests it.
- *
- * Their parents will be scanned too. The paths don't start with a /.
- */
- std::set<QByteArray> locally_touched_dirs;
+ std::function<bool(const QByteArray &)> should_discover_locally_fn;
bool ignore_hidden_files = true;
diff --git a/src/csync/csync_update.cpp b/src/csync/csync_update.cpp
index 9ce636476..12ede9161 100644
--- a/src/csync/csync_update.cpp
+++ b/src/csync/csync_update.cpp
@@ -569,23 +569,12 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
bool do_read_from_db = (ctx->current == REMOTE_REPLICA && ctx->remote.read_from_db);
const char *db_uri = uri;
- if (ctx->current == LOCAL_REPLICA
- && ctx->local_discovery_style == LocalDiscoveryStyle::DatabaseAndFilesystem) {
+ if (ctx->current == LOCAL_REPLICA && ctx->should_discover_locally_fn) {
const char *local_uri = uri + strlen(ctx->local.uri);
if (*local_uri == '/')
++local_uri;
db_uri = local_uri;
- do_read_from_db = true;
-
- // Minor bug: local_uri doesn't have a trailing /. Example: Assume it's "d/foo"
- // and we want to check whether we should read from the db. Assume "d/foo a" is
- // in locally_touched_dirs. Then this check will say no, don't read from the db!
- // (because "d/foo" < "d/foo a" < "d/foo/bar")
- // C++14: Could skip the conversion to QByteArray here.
- auto it = ctx->locally_touched_dirs.lower_bound(QByteArray(local_uri));
- if (it != ctx->locally_touched_dirs.end() && it->startsWith(local_uri)) {
- do_read_from_db = false;
- }
+ do_read_from_db = !ctx->should_discover_locally_fn(QByteArray(local_uri));
}
if (!depth) {
diff --git a/src/gui/issueswidget.cpp b/src/gui/issueswidget.cpp
index b49afb9c2..15de3f107 100644
--- a/src/gui/issueswidget.cpp
+++ b/src/gui/issueswidget.cpp
@@ -222,7 +222,6 @@ void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &p
return;
const auto &engine = f->syncEngine();
const auto style = engine.lastLocalDiscoveryStyle();
- const auto &discoveryDirs = engine.currentLocalDiscoveryDirs();
cleanItems([&](QTreeWidgetItem *item) {
if (ProtocolItem::folderName(item) != folder)
return false;
@@ -239,9 +238,7 @@ void IssuesWidget::slotProgressInfo(const QString &folder, const ProgressInfo &p
if (path == ".")
path.clear();
- // TODO: This logic has to match csync_ftw's
- auto it = discoveryDirs.lower_bound(path);
- return it != discoveryDirs.end() && it->startsWith(path);
+ return engine.shouldDiscoverLocally(path);
});
}
}
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index 958df186c..0361d4a60 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -860,7 +860,11 @@ void SyncEngine::startSync()
_excludedFiles->setExcludeConflictFiles(!_account->capabilities().uploadConflictFiles());
_csync_ctx->read_remote_from_db = true;
- _lastLocalDiscoveryStyle = _csync_ctx->local_discovery_style;
+
+ _lastLocalDiscoveryStyle = _localDiscoveryStyle;
+ _csync_ctx->should_discover_locally_fn = [this](const QByteArray &path) {
+ return shouldDiscoverLocally(path);
+ };
bool ok;
auto selectiveSyncBlackList = _journal->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
@@ -1084,6 +1088,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
// Re-init the csync context to free memory
_csync_ctx->reinitialize();
+ _localDiscoveryPaths.clear();
// To announce the beginning of the sync
emit aboutToPropagate(syncItems);
@@ -1225,6 +1230,8 @@ void SyncEngine::finalize(bool success)
_temporarilyUnavailablePaths.clear();
_renamedFolders.clear();
_uniqueErrors.clear();
+ _localDiscoveryPaths.clear();
+ _localDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
_clearTouchedFilesTimer.start();
}
@@ -1631,13 +1638,32 @@ AccountPtr SyncEngine::account() const
void SyncEngine::setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> dirs)
{
- _csync_ctx->local_discovery_style = style;
- _csync_ctx->locally_touched_dirs = std::move(dirs);
+ _localDiscoveryStyle = style;
+ _localDiscoveryPaths = std::move(dirs);
}
-const std::set<QByteArray> &SyncEngine::currentLocalDiscoveryDirs() const
+bool SyncEngine::shouldDiscoverLocally(const QByteArray &path) const
{
- return _csync_ctx->locally_touched_dirs;
+ if (_localDiscoveryStyle == LocalDiscoveryStyle::FilesystemOnly)
+ return true;
+
+ auto it = _localDiscoveryPaths.lower_bound(path);
+ if (it == _localDiscoveryPaths.end() || !it->startsWith(path))
+ return false;
+
+ // maybe an exact match or an empty path?
+ if (it->size() == path.size() || path.isEmpty())
+ return true;
+
+ // check for a prefix + / match
+ forever {
+ if (it->size() > path.size() && it->at(path.size()) == '/')
+ return true;
+ ++it;
+ if (it == _localDiscoveryPaths.end() || !it->startsWith(path))
+ return false;
+ }
+ return false;
}
void SyncEngine::abort()
diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h
index 8e3bb5b86..aba6164de 100644
--- a/src/libsync/syncengine.h
+++ b/src/libsync/syncengine.h
@@ -114,11 +114,13 @@ public:
void setLocalDiscoveryOptions(LocalDiscoveryStyle style, std::set<QByteArray> dirs = {});
/**
- * Access the dirs that shall be rediscovered for DatabaseAndFilesystem discovery.
+ * Returns whether the given folder-relative path should be locally discovered
+ * given the local discovery options.
*
- * This is only valid during Discovery and Reconcile phases of the sync run.
+ * Example: If path is 'foo/bar' and style is DatabaseAndFilesystem and dirs contains
+ * 'foo/bar/touched_file', then the result will be true.
*/
- const std::set<QByteArray> &currentLocalDiscoveryDirs() const;
+ bool shouldDiscoverLocally(const QByteArray &path) const;
/** Access the last sync run's local discovery style */
LocalDiscoveryStyle lastLocalDiscoveryStyle() const { return _lastLocalDiscoveryStyle; }
@@ -308,7 +310,9 @@ private:
QSet<QString> _uniqueErrors;
/** The kind of local discovery the last sync run used */
- LocalDiscoveryStyle _lastLocalDiscoveryStyle = LocalDiscoveryStyle::DatabaseAndFilesystem;
+ LocalDiscoveryStyle _lastLocalDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
+ LocalDiscoveryStyle _localDiscoveryStyle = LocalDiscoveryStyle::FilesystemOnly;
+ std::set<QByteArray> _localDiscoveryPaths;
};
}
diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp
index 6ac5ed549..10644abd0 100644
--- a/test/testsyncengine.cpp
+++ b/test/testsyncengine.cpp
@@ -605,6 +605,38 @@ private slots:
QCOMPARE(fakeFolder.syncEngine().lastLocalDiscoveryStyle(), LocalDiscoveryStyle::FilesystemOnly);
}
+ void testLocalDiscoveryDecision()
+ {
+ FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
+ auto &engine = fakeFolder.syncEngine();
+
+ QVERIFY(engine.shouldDiscoverLocally(""));
+ QVERIFY(engine.shouldDiscoverLocally("A"));
+ QVERIFY(engine.shouldDiscoverLocally("A/X"));
+
+ fakeFolder.syncEngine().setLocalDiscoveryOptions(
+ LocalDiscoveryStyle::DatabaseAndFilesystem,
+ { "A/X", "foo bar space/touch", "foo/", "zzz" });
+
+ QVERIFY(engine.shouldDiscoverLocally(""));
+ QVERIFY(engine.shouldDiscoverLocally("A"));
+ QVERIFY(engine.shouldDiscoverLocally("A/X"));
+ QVERIFY(!engine.shouldDiscoverLocally("B"));
+ QVERIFY(!engine.shouldDiscoverLocally("A B"));
+ QVERIFY(!engine.shouldDiscoverLocally("B/X"));
+ QVERIFY(!engine.shouldDiscoverLocally("A/X/Y"));
+ QVERIFY(engine.shouldDiscoverLocally("foo bar space"));
+ QVERIFY(engine.shouldDiscoverLocally("foo"));
+ QVERIFY(!engine.shouldDiscoverLocally("foo bar"));
+ QVERIFY(!engine.shouldDiscoverLocally("foo bar/touch"));
+
+ fakeFolder.syncEngine().setLocalDiscoveryOptions(
+ LocalDiscoveryStyle::DatabaseAndFilesystem,
+ {});
+
+ QVERIFY(!engine.shouldDiscoverLocally(""));
+ }
+
void testDiscoveryHiddenFile()
{
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };