[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [sink/develop] /: Ensure blooming queries filter as they should
From:       Christian Mollekopf <null () kde ! org>
Date:       2017-01-31 19:33:31
Message-ID: E1cYeBH-0005xb-Im () code ! kde ! org
[Download RAW message or body]

Git commit 871a048580d5a464fb697713a5e0e2c52dee5208 by Christian Mollekopf.
Committed on 31/01/2017 at 18:38.
Pushed by cmollekopf into branch 'develop'.

Ensure blooming queries filter as they should

After the initial bloom, it should turn into a regular filter.

M  +29   -17   common/datastorequery.cpp
M  +1    -0    common/domain/applicationdomaintype.cpp
M  +92   -0    tests/querytest.cpp

https://commits.kde.org/sink/871a048580d5a464fb697713a5e0e2c52dee5208

diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index d90d546..087f405 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -101,7 +101,7 @@ public:
 
     virtual ~Filter(){}
 
-    bool next(const std::function<void(const ResultSet::Result &result)> &callback) \
Q_DECL_OVERRIDE { +    virtual bool next(const std::function<void(const \
ResultSet::Result &result)> &callback) Q_DECL_OVERRIDE {  bool foundValue = false;
         while(!foundValue && mSource->next([this, callback, &foundValue](const \
                ResultSet::Result &result) {
                 SinkTrace() << "Filter: " << result.entity.identifier() << \
result.operation; @@ -273,14 +273,14 @@ public:
     }
 };
 
-class Bloom : public FilterBase {
+class Bloom : public Filter {
 public:
     typedef QSharedPointer<Bloom> Ptr;
 
     QByteArray mBloomProperty;
 
     Bloom(const QByteArray &bloomProperty, FilterBase::Ptr source, DataStoreQuery \
                *store)
-        : FilterBase(source, store),
+        : Filter(source, store),
         mBloomProperty(bloomProperty)
     {
 
@@ -289,21 +289,33 @@ public:
     virtual ~Bloom(){}
 
     bool next(const std::function<void(const ResultSet::Result &result)> &callback) \
                Q_DECL_OVERRIDE {
-        bool foundValue = false;
-        while(!foundValue && mSource->next([this, callback, &foundValue](const \
                ResultSet::Result &result) {
-                auto bloomValue = result.entity.getProperty(mBloomProperty);
-                auto results = indexLookup(mBloomProperty, bloomValue);
-                for (const auto &r : results) {
-                    readEntity(r, [&, this](const \
                Sink::ApplicationDomain::ApplicationDomainType &entity, \
                Sink::Operation operation) {
-                        callback({entity, Sink::Operation_Creation});
-                        foundValue = true;
-                    });
-                }
-                return false;
-            }))
-        {}
-        return foundValue;
+        if (!mBloomed) {
+            //Initially we bloom on the first value that matches.
+            //From there on we just filter.
+            bool foundValue = false;
+            while(!foundValue && mSource->next([this, callback, &foundValue](const \
ResultSet::Result &result) { +                    mBloomValue = \
result.entity.getProperty(mBloomProperty); +                    auto results = \
indexLookup(mBloomProperty, mBloomValue); +                    SinkWarning() << \
"Bloomed on value " << mBloomValue << " and found " << results.size(); +              \
for (const auto &r : results) { +                        readEntity(r, [&, \
this](const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Operation \
operation) { +                            callback({entity, \
Sink::Operation_Creation}); +                            foundValue = true;
+                        });
+                    }
+                    return false;
+                }))
+            {}
+            mBloomed = true;
+            propertyFilter.insert(mBloomProperty, mBloomValue);
+            return foundValue;
+        } else {
+            //Filter on bloom value
+            return Filter::next(callback);
+        }
     }
+    QVariant mBloomValue;
+    bool mBloomed = false;
 };
 
 DataStoreQuery::DataStoreQuery(const Sink::QueryBase &query, const QByteArray &type, \
                EntityStore &store)
diff --git a/common/domain/applicationdomaintype.cpp \
b/common/domain/applicationdomaintype.cpp index 6d16a3c..57d0f2d 100644
--- a/common/domain/applicationdomaintype.cpp
+++ b/common/domain/applicationdomaintype.cpp
@@ -30,6 +30,7 @@ namespace Sink {
 namespace ApplicationDomain {
 
 constexpr const char *Mail::ThreadId::name;
+constexpr const char *Mail::Folder::name;
 
 static const int foo = [] {
     QMetaType::registerEqualsComparator<Reference>();
diff --git a/tests/querytest.cpp b/tests/querytest.cpp
index 92fc1f7..10f5567 100644
--- a/tests/querytest.cpp
+++ b/tests/querytest.cpp
@@ -11,6 +11,7 @@
 #include "modelresult.h"
 #include "test.h"
 #include "testutils.h"
+#include "applicationdomaintype.h"
 
 using namespace Sink;
 using namespace Sink::ApplicationDomain;
@@ -632,6 +633,7 @@ private slots:
         auto folders = Sink::Store::read<Folder>(query);
         QCOMPARE(folders.size(), 1);
     }
+
     void testLivequeryUnmatchInThread()
     {
         // Setup
@@ -707,6 +709,96 @@ private slots:
         auto mail = model->data(model->index(0, 0, QModelIndex{}), \
Sink::Store::DomainObjectRole).value<Mail::Ptr>();  QCOMPARE(mail->getUnread(), \
true);  }
+
+    void testBloom()
+    {
+        // Setup
+        auto folder1 = Folder::createEntity<Folder>("sink.dummy.instance1");
+        VERIFYEXEC(Sink::Store::create<Folder>(folder1));
+
+        auto folder2 = Folder::createEntity<Folder>("sink.dummy.instance1");
+        VERIFYEXEC(Sink::Store::create<Folder>(folder2));
+
+        auto mail1 = Mail::createEntity<Mail>("sink.dummy.instance1");
+        mail1.setUid("mail1");
+        mail1.setFolder(folder1);
+        VERIFYEXEC(Sink::Store::create(mail1));
+
+        // Ensure all local data is processed
+        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
 +
+        {
+            auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
+            mail.setUid("mail2");
+            mail.setFolder(folder1);
+            VERIFYEXEC(Sink::Store::create(mail));
+        }
+        {
+            auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
+            mail.setUid("mail3");
+            mail.setFolder(folder2);
+            VERIFYEXEC(Sink::Store::create(mail));
+        }
+        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
 +
+        Query query;
+        query.setId("testFilterCreationInThread");
+        query.filter(mail1.identifier());
+        query.bloom<Mail::Folder>();
+        query.request<Mail::Folder>();
+
+        auto model = Sink::Store::loadModel<Mail>(query);
+        QTRY_VERIFY(model->data(QModelIndex(), \
Sink::Store::ChildrenFetchedRole).toBool()); +        QCOMPARE(model->rowCount(), 2);
+    }
+
+    void testLivequeryFilterCreationInThread()
+    {
+        // Setup
+        auto folder1 = Folder::createEntity<Folder>("sink.dummy.instance1");
+        VERIFYEXEC(Sink::Store::create<Folder>(folder1));
+
+        auto folder2 = Folder::createEntity<Folder>("sink.dummy.instance1");
+        VERIFYEXEC(Sink::Store::create<Folder>(folder2));
+
+        auto mail1 = Mail::createEntity<Mail>("sink.dummy.instance1");
+        mail1.setUid("mail1");
+        mail1.setFolder(folder1);
+        VERIFYEXEC(Sink::Store::create(mail1));
+
+        // Ensure all local data is processed
+        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
 +
+        Query query;
+        query.setId("testFilterCreationInThread");
+        query.filter(mail1.identifier());
+        query.bloom<Mail::Folder>();
+        query.sort<Mail::Date>();
+        query.setFlags(Query::LiveQuery);
+        query.request<Mail::Unread>();
+        query.request<Mail::Folder>();
+
+        auto model = Sink::Store::loadModel<Mail>(query);
+        QTRY_COMPARE(model->rowCount(), 1);
+
+        {
+            auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
+            mail.setUid("mail2");
+            mail.setFolder(folder1);
+            VERIFYEXEC(Sink::Store::create(mail));
+        }
+        {
+            auto mail = Mail::createEntity<Mail>("sink.dummy.instance1");
+            mail.setUid("mail3");
+            mail.setFolder(folder2);
+            VERIFYEXEC(Sink::Store::create(mail));
+        }
+        VERIFYEXEC(Sink::ResourceControl::flushMessageQueue("sink.dummy.instance1"));
 +
+        QTRY_COMPARE(model->rowCount(), 2);
+        QTest::qWait(100);
+        QCOMPARE(model->rowCount(), 2);
+    }
 };
 
 QTEST_MAIN(QueryTest)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic