diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp index 2ae2059086..a57d4b952b 100644 --- a/src/libsync/owncloudpropagator.cpp +++ b/src/libsync/owncloudpropagator.cpp @@ -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. diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index bd3eeda220..af944e8e94 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -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); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 7cd52fdf72..eb71dd01ff 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -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"; }