Harmonizing sorting algorithm (again)

Signed-off-by: Dominique Fuchs <32204802+DominiqueFuchs@users.noreply.github.com>
This commit is contained in:
Dominique Fuchs 2019-09-28 09:17:12 +02:00
parent 3269402f48
commit 10a5e75cd8
3 changed files with 59 additions and 27 deletions

View 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.

View 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);

View 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";
}