From ce7c9ae13defe17f0966638d63d9f7f55806ac76 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 2 Jul 2018 14:33:21 +0200 Subject: Fixed yet another reduction update codepath --- common/datastorequery.cpp | 14 ++++++-------- tests/querytest.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index fd910f8..4c25710 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp @@ -361,10 +361,6 @@ public: auto oldSelectionResult = mSelectedValues.take(reductionValueBa); SinkTraceCtx(mDatastore->mLogCtx) << "Old selection result: " << oldSelectionResult << " New selection result: " << selectionResult.selection; - //If mSelectedValues did not containthe value, oldSelectionResult will be empty.(Happens if entites have been filtered) - if (oldSelectionResult.isEmpty()) { - return; - } if (oldSelectionResult == selectionResult.selection) { mSelectedValues.insert(reductionValueBa, selectionResult.selection); Q_ASSERT(!selectionResult.selection.isEmpty()); @@ -373,10 +369,12 @@ public: }); } else { //remove old result - Q_ASSERT(!oldSelectionResult.isEmpty()); - readEntity(oldSelectionResult, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) { - callback({entity, Sink::Operation_Removal}); - }); + //If mSelectedValues did not containthe value, oldSelectionResult will be empty.(Happens if entites have been filtered) + if (!oldSelectionResult.isEmpty()) { + readEntity(oldSelectionResult, [&](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation) { + callback({entity, Sink::Operation_Removal}); + }); + } //If the last item has been removed, then there's nothing to add if (!selectionResult.selection.isEmpty()) { diff --git a/tests/querytest.cpp b/tests/querytest.cpp index 7685086..f320d57 100644 --- a/tests/querytest.cpp +++ b/tests/querytest.cpp @@ -1008,6 +1008,53 @@ private slots: QTRY_COMPARE(model->rowCount(), 1); } + /* + * Two messages in the same thread. The first get's filtered, the second one makes it. + */ + void testFilteredReductionUpdateInSameThread() + { + // Setup + auto folder1 = Folder::createEntity("sink.dummy.instance1"); + VERIFYEXEC(Sink::Store::create(folder1)); + + auto folder2 = Folder::createEntity("sink.dummy.instance1"); + VERIFYEXEC(Sink::Store::create(folder2)); + + // Ensure all local data is processed + VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1")); + + Query query; + query.setId("testFilteredReductionUpdate"); + query.setFlags(Query::LiveQuery); + query.filter(folder1); + query.reduce(Query::Reduce::Selector::max()); + + auto model = Sink::Store::loadModel(query); + QTRY_VERIFY(model->data(QModelIndex(), Sink::Store::ChildrenFetchedRole).toBool()); + QCOMPARE(model->rowCount(), 0); + + //The first message will be filtered (but would be aggreagted together with the message that passes) + { + auto mail = Mail::createEntity("sink.dummy.instance1"); + mail.setExtractedMessageId("aggregatedId"); + mail.setFolder(folder2); + VERIFYEXEC(Sink::Store::create(mail)); + } + + VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1")); + QCOMPARE(model->rowCount(), 0); + + //Ensure the non-filtered still gets through. + { + auto mail = Mail::createEntity("sink.dummy.instance1"); + mail.setExtractedMessageId("aggregatedId"); + mail.setFolder(folder1); + VERIFYEXEC(Sink::Store::create(mail)); + } + VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1")); + QTRY_COMPARE(model->rowCount(), 1); + } + void testBloom() { // Setup -- cgit v1.2.3