New discovery algorithm: More work on virtual files
authorOlivier Goffart <ogoffart@woboq.com>
Wed, 18 Jul 2018 09:13:46 +0000 (11:13 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:57:59 +0000 (10:57 +0100)
src/libsync/discovery.cpp

index 5a50992d1a7cf83963a1cc59406767a5de8d5fe2..d2cba8c968621cdf9acebd7b4494b694d0727d6b 100644 (file)
@@ -179,6 +179,8 @@ void ProcessDirectoryJob::process()
         if (e.name.endsWith(_discoveryData->_syncOptions._virtualFileSuffix)) {
             e.isVirtualFile = true;
             name = e.name.left(e.name.size() - _discoveryData->_syncOptions._virtualFileSuffix.size());
+            if (localEntriesHash.contains(name))
+                continue; // If there is both a virtual file and a real file, we must keep the real file
         }
         entriesNames.insert(name);
         localEntriesHash[name] = std::move(e);
@@ -607,10 +609,16 @@ void ProcessDirectoryJob::processFile(PathTuple path,
         } else {
             recurseQueryServer = ParentNotChanged;
         }
+    } else if (_queryServer == ParentNotChanged && dbEntry._type == ItemTypeVirtualFileDownload) {
+        item->_direction = SyncFileItem::Down;
+        item->_instruction = CSYNC_INSTRUCTION_NEW;
+        Q_ASSERT(item->_file.endsWith(_discoveryData->_syncOptions._virtualFileSuffix));
+        item->_file.chop(_discoveryData->_syncOptions._virtualFileSuffix.size());
+        item->_type = ItemTypeVirtualFileDownload;
     }
     bool serverModified = item->_instruction == CSYNC_INSTRUCTION_NEW || item->_instruction == CSYNC_INSTRUCTION_SYNC
         || item->_instruction == CSYNC_INSTRUCTION_RENAME || item->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE;
-    if ((dbEntry.isValid() && dbEntry._type == ItemTypeVirtualFile) || (localEntry.isValid() && localEntry.isVirtualFile)) {
+    if ((dbEntry.isValid() && dbEntry._type == ItemTypeVirtualFile) || (localEntry.isValid() && localEntry.isVirtualFile && item->_type != ItemTypeVirtualFileDownload)) {
         // Do not download virtual files
         if (serverModified || dbEntry._type != ItemTypeVirtualFile)
             item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
@@ -624,13 +632,11 @@ void ProcessDirectoryJob::processFile(PathTuple path,
         item->_inode = localEntry.inode;
         bool typeChange = dbEntry.isValid() && localEntry.isDirectory != (dbEntry._type == ItemTypeDirectory);
         if (localEntry.isVirtualFile) {
-            item->_type = ItemTypeVirtualFile;
+            if (item->_type != ItemTypeVirtualFileDownload)
+                item->_type = ItemTypeVirtualFile;
             if (_queryServer != ParentNotChanged && !serverEntry.isValid()) {
                 item->_instruction = CSYNC_INSTRUCTION_REMOVE;
                 item->_direction = SyncFileItem::Down;
-            } else if (dbEntry._inode != localEntry.inode) {
-                item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-                item->_direction = SyncFileItem::Down; // Does not matter
             }
         } else if (dbEntry.isValid() && !typeChange && ((dbEntry._modtime == localEntry.modtime && dbEntry._fileSize == localEntry.size) || (localEntry.isDirectory && dbEntry._type == ItemTypeDirectory))) {
             // Local file unchanged.
@@ -641,7 +647,7 @@ void ProcessDirectoryJob::processFile(PathTuple path,
                 item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
                 item->_direction = SyncFileItem::Down; // Does not matter
             }
-        } else if (serverModified) {
+        } else if (serverModified || dbEntry._type == ItemTypeVirtualFile) {
             if (serverEntry.isDirectory && localEntry.isDirectory) {
                 // Folders of the same path are always considered equals
                 item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
@@ -698,6 +704,14 @@ void ProcessDirectoryJob::processFile(PathTuple path,
                 }
             }
             item->_direction = item->_instruction == CSYNC_INSTRUCTION_CONFLICT ? SyncFileItem::None : SyncFileItem::Down;
+            if (dbEntry._type == ItemTypeVirtualFile)
+                item->_type = ItemTypeVirtualFileDownload;
+            if (item->_file.endsWith(_discoveryData->_syncOptions._virtualFileSuffix)) {
+                item->_file.chop(_discoveryData->_syncOptions._virtualFileSuffix.size());
+                item->_type = ItemTypeVirtualFileDownload;
+            }
+            item->_previousSize = localEntry.size;
+            item->_previousModtime = localEntry.modtime;
         } else if (typeChange) {
             item->_instruction = CSYNC_INSTRUCTION_TYPE_CHANGE;
             item->_direction = SyncFileItem::Up;