Harmonizing sorting algorithm (again)
authorDominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
Sat, 28 Sep 2019 07:17:12 +0000 (09:17 +0200)
committerDominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
Sat, 28 Sep 2019 07:17:12 +0000 (09:17 +0200)
Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
src/libsync/owncloudpropagator.cpp
src/libsync/owncloudpropagator.h
src/libsync/syncengine.cpp

index 2ae2059086252c816ffa17ff01c4e5007b54fe54..a57d4b952b631ecb37523866e7ad2a5b357b8276 100644 (file)
@@ -366,19 +366,28 @@ quint64 OwncloudPropagator::smallFileSize()
     return smallFileSize;
 }
 
-void OwncloudPropagator::start(const SyncFileItemVector &items, const bool &hasDelete, const int lastDeleteInstruction)
+void OwncloudPropagator::start(const SyncFileItemVector &items,
+                                                               const bool &hasChange,
+                                                               const int &lastChangeInstruction,
+                                                               const bool &hasDelete,
+                                                               const int &lastDeleteInstruction)
 {
-    if (hasDelete) {
+    if (!hasChange && !hasDelete) {
+        Q_ASSERT(std::is_sorted(items.begin(), items.end()));
+    } else if (hasChange) {
         Q_ASSERT(std::is_sorted(items.begin(), items.end(),
             [](const SyncFileItemVector::const_reference &a, const SyncFileItemVector::const_reference &b) -> bool {
-                return ((a->_instruction == 0x00000002) && (b->_instruction != 0x00000002));
+                return ((a->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) && (b->_instruction != CSYNC_INSTRUCTION_TYPE_CHANGE));
             }));
-        Q_ASSERT(std::is_sorted(items.begin(), items.begin() + lastDeleteInstruction));
-        if (items.count() > 1) {
-            Q_ASSERT(std::is_sorted(items.begin() + (lastDeleteInstruction + 1), items.end()));
+        Q_ASSERT(std::is_sorted(items.begin(), items.begin() + lastChangeInstruction));
+
+        if (hasDelete) {
+            Q_ASSERT(std::is_sorted(items.begin() + (lastChangeInstruction + 1), items.end(),
+                [](const SyncFileItemVector::const_reference &a, const SyncFileItemVector::const_reference &b) -> bool {
+                    return ((a->_instruction == CSYNC_INSTRUCTION_REMOVE) && (b->_instruction != CSYNC_INSTRUCTION_REMOVE));
+                }));
+            Q_ASSERT(std::is_sorted(items.begin() + (lastChangeInstruction + 1), items.begin() + lastDeleteInstruction));
         }
-    } else {
-        Q_ASSERT(std::is_sorted(items.begin(), items.end()));
        }
 
     /* This builds all the jobs needed for the propagation.
index bd3eeda2200dba299e2960a1fc04d05e41df6ec1..af944e8e9455730e650de833c86fb2988c7f8fe2 100644 (file)
@@ -384,7 +384,11 @@ public:
 
     ~OwncloudPropagator();
 
-    void start(const SyncFileItemVector &_syncedItems, const bool &hasDelete, const int lastDeleteInstruction = 0);
+    void start(const SyncFileItemVector &_syncedItems,
+               const bool &hasChange = false,
+               const int &lastChangeInstruction = 0,
+               const bool &hasDelete = false,
+               const int &lastDeleteInstruction = 0);
 
     const SyncOptions &syncOptions() const;
     void setSyncOptions(const SyncOptions &syncOptions);
index 7cd52fdf72825639b1626c03e67ddd07be0906ff..eb71dd01ffbf4d8120affba46be50f02c994a04e 100644 (file)
@@ -1069,35 +1069,54 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
         }
     }
 
+       bool hasChange = false;
        bool hasDelete = false;
+    int lastChangeInstruction = 0;
     int lastDeleteInstruction = 0;
 
-    //Get REMOVE instructions to the top
-    std::sort(syncItems.begin(), syncItems.end(),
-        [](const SyncFileItemVector::const_reference &a, const SyncFileItemVector::const_reference &b) -> bool {
-            return ((a->_instruction == 0x00000002) && (b->_instruction != 0x00000002));
-        });
-
-       if (syncItems.count() > 0) {
-        // We have at least one REMOVE instruction in the list
-        if (syncItems.at(0)->_instruction == csync_instructions_e::CSYNC_INSTRUCTION_REMOVE) {
-            hasDelete = true;
-            // as long as vector continues and instruction of current item is REMOVE
-            for (SyncFileItemVector::iterator it = syncItems.begin();
-                 it != syncItems.end() && (*it)->_instruction == csync_instructions_e::CSYNC_INSTRUCTION_REMOVE; ++it) {
-                lastDeleteInstruction = std::distance(syncItems.begin(), it);
+       // Only if list is populated, can be empty under certain circumstances
+    // Get CHANGE instructions to the top first
+    if (syncItems.count() > 0) {
+        std::sort(syncItems.begin(), syncItems.end(),
+            [](const SyncFileItemVector::const_reference &a, const SyncFileItemVector::const_reference &b) -> bool {
+                               return ((a->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) && (b->_instruction != CSYNC_INSTRUCTION_TYPE_CHANGE));
+            });
+        if (syncItems.at(0)->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE) {
+            hasChange = true;
+            lastChangeInstruction = std::distance(syncItems.begin(), std::find_if(syncItems.begin(), syncItems.end(), [](SyncFileItemVector::const_reference &a) -> bool { return a->_instruction != CSYNC_INSTRUCTION_TYPE_CHANGE; }));
+        }
+        if (hasChange) {
+            std::sort(syncItems.begin(), syncItems.begin() + lastChangeInstruction);
+            if (syncItems.count() > lastChangeInstruction) {
+                std::sort(syncItems.begin() + (lastChangeInstruction + 1), syncItems.end(),
+                    [](const SyncFileItemVector::const_reference &a, const SyncFileItemVector::const_reference &b) -> bool {
+                        return ((a->_instruction == CSYNC_INSTRUCTION_REMOVE) && (b->_instruction != CSYNC_INSTRUCTION_REMOVE));
+                    });
+                if (syncItems.at(lastChangeInstruction + 1)->_instruction == CSYNC_INSTRUCTION_REMOVE) {
+                    hasDelete = true;
+                    lastDeleteInstruction = std::distance(syncItems.begin(), std::find_if(syncItems.begin() + (lastChangeInstruction + 1), syncItems.end(), [](SyncFileItemVector::const_reference &a) -> bool { return a->_instruction != CSYNC_INSTRUCTION_REMOVE; }));
+                    std::sort(syncItems.begin() + (lastChangeInstruction + 1), syncItems.begin() + lastDeleteInstruction);
+                    if (syncItems.count() > lastDeleteInstruction) {
+                        std::sort(syncItems.begin() + (lastDeleteInstruction + 1), syncItems.end());
+                    }
+                } else {
+                    std::sort(syncItems.begin() + (lastChangeInstruction + 1), syncItems.end());
+                }
             }
-            // sort REMOVE and all other items separately for destination
+        } else if (syncItems.at(0)->_instruction == CSYNC_INSTRUCTION_REMOVE) {
+            hasDelete = true;
+            lastDeleteInstruction = std::distance(syncItems.begin(), std::find_if(syncItems.begin(), syncItems.end(), [](SyncFileItemVector::const_reference &a) -> bool { return a->_instruction != CSYNC_INSTRUCTION_REMOVE; }));
             std::sort(syncItems.begin(), syncItems.begin() + lastDeleteInstruction);
-            if (syncItems.count() > 1) {
+                       if (syncItems.count() > lastDeleteInstruction) {
                 std::sort(syncItems.begin() + (lastDeleteInstruction + 1), syncItems.end());
             }
         } else {
-            // just sort whole vector for destination
             std::sort(syncItems.begin(), syncItems.end());
         }
     }
 
+    //std::sort(syncItems.begin(), syncItems.end());
+
     // make sure everything is allowed
     checkForPermission(syncItems);
 
@@ -1154,7 +1173,7 @@ void SyncEngine::slotDiscoveryJobFinished(int discoveryResult)
     if (_needsUpdate)
         emit(started());
 
-    _propagator->start(syncItems, hasDelete, lastDeleteInstruction);
+    _propagator->start(syncItems, hasChange, lastChangeInstruction, hasDelete, lastDeleteInstruction);
 
     qCInfo(lcEngine) << "#### Post-Reconcile end #################################################### " << _stopWatch.addLapTime(QLatin1String("Post-Reconcile Finished")) << "ms";
 }