diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-09-26 14:19:44 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-09-26 14:19:44 +0200 |
commit | 47b9f2109f57c1121b760ea6d885ab08f12c46b3 (patch) | |
tree | c65e57788d5fda221a9369353bb469cbd6a066c3 | |
parent | be8dba1827ec54ec11d9a3ef143db9ad7f7f38df (diff) | |
download | sink-47b9f2109f57c1121b760ea6d885ab08f12c46b3.tar.gz sink-47b9f2109f57c1121b760ea6d885ab08f12c46b3.zip |
Blooming
-rw-r--r-- | common/datastorequery.cpp | 37 | ||||
-rw-r--r-- | common/query.h | 5 | ||||
-rw-r--r-- | tests/mailthreadtest.cpp | 28 |
3 files changed, 65 insertions, 5 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index 7c0fdea..f352b74 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -214,6 +214,39 @@ public: | |||
214 | } | 214 | } |
215 | }; | 215 | }; |
216 | 216 | ||
217 | class Bloom : public FilterBase { | ||
218 | public: | ||
219 | typedef QSharedPointer<Bloom> Ptr; | ||
220 | |||
221 | QByteArray mBloomProperty; | ||
222 | |||
223 | Bloom(const QByteArray &bloomProperty, FilterBase::Ptr source, DataStoreQuery *store) | ||
224 | : FilterBase(source, store), | ||
225 | mBloomProperty(bloomProperty) | ||
226 | { | ||
227 | |||
228 | } | ||
229 | |||
230 | virtual ~Bloom(){} | ||
231 | |||
232 | bool next(const std::function<void(Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer)> &callback) Q_DECL_OVERRIDE { | ||
233 | bool foundValue = false; | ||
234 | while(!foundValue && mSource->next([this, callback, &foundValue](Sink::Operation operation, const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | ||
235 | auto bloomValue = getProperty(entityBuffer.entity(), mBloomProperty); | ||
236 | auto results = indexLookup(mBloomProperty, bloomValue); | ||
237 | for (const auto r : results) { | ||
238 | readEntity(r, [&, this](const QByteArray &uid, const Sink::EntityBuffer &entityBuffer) { | ||
239 | callback(Sink::Operation_Creation, uid, entityBuffer); | ||
240 | foundValue = true; | ||
241 | }); | ||
242 | } | ||
243 | return false; | ||
244 | })) | ||
245 | {} | ||
246 | return foundValue; | ||
247 | } | ||
248 | }; | ||
249 | |||
217 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) | 250 | DataStoreQuery::DataStoreQuery(const Sink::Query &query, const QByteArray &type, Sink::Storage::Transaction &transaction, TypeIndex &typeIndex, std::function<QVariant(const Sink::Entity &entity, const QByteArray &property)> getProperty) |
218 | : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) | 251 | : mQuery(query), mTransaction(transaction), mType(type), mTypeIndex(typeIndex), mDb(Storage::mainDatabase(mTransaction, mType)), mGetProperty(getProperty) |
219 | { | 252 | { |
@@ -383,6 +416,10 @@ void DataStoreQuery::setupQuery() | |||
383 | auto reduce = Reduce::Ptr::create("threadId", "date", Reduce::Max, baseSet, this); | 416 | auto reduce = Reduce::Ptr::create("threadId", "date", Reduce::Max, baseSet, this); |
384 | baseSet = reduce; | 417 | baseSet = reduce; |
385 | } | 418 | } |
419 | if (mQuery.bloomThread) { | ||
420 | auto reduce = Bloom::Ptr::create("threadId", baseSet, this); | ||
421 | baseSet = reduce; | ||
422 | } | ||
386 | 423 | ||
387 | mCollector = Collector::Ptr::create(baseSet, this); | 424 | mCollector = Collector::Ptr::create(baseSet, this); |
388 | } | 425 | } |
diff --git a/common/query.h b/common/query.h index 0808432..1b909e5 100644 --- a/common/query.h +++ b/common/query.h | |||
@@ -195,13 +195,13 @@ public: | |||
195 | return *this; | 195 | return *this; |
196 | } | 196 | } |
197 | 197 | ||
198 | Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false) | 198 | Query(const ApplicationDomain::Entity &value) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false), bloomThread(false) |
199 | { | 199 | { |
200 | ids << value.identifier(); | 200 | ids << value.identifier(); |
201 | resources << value.resourceInstanceIdentifier(); | 201 | resources << value.resourceInstanceIdentifier(); |
202 | } | 202 | } |
203 | 203 | ||
204 | Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false) | 204 | Query(Flags flags = Flags()) : limit(0), liveQuery(false), synchronousQuery(false), threadLeaderOnly(false), bloomThread(false) |
205 | { | 205 | { |
206 | } | 206 | } |
207 | 207 | ||
@@ -237,6 +237,7 @@ public: | |||
237 | bool liveQuery; | 237 | bool liveQuery; |
238 | bool synchronousQuery; | 238 | bool synchronousQuery; |
239 | bool threadLeaderOnly; | 239 | bool threadLeaderOnly; |
240 | bool bloomThread; | ||
240 | }; | 241 | }; |
241 | } | 242 | } |
242 | 243 | ||
diff --git a/tests/mailthreadtest.cpp b/tests/mailthreadtest.cpp index a3df56b..89e5a85 100644 --- a/tests/mailthreadtest.cpp +++ b/tests/mailthreadtest.cpp | |||
@@ -133,6 +133,21 @@ void MailThreadTest::testIndexInMixedOrder() | |||
133 | query.sort<Mail::Date>(); | 133 | query.sort<Mail::Date>(); |
134 | query.filter<Mail::Folder>(folder); | 134 | query.filter<Mail::Folder>(folder); |
135 | 135 | ||
136 | Mail threadLeader; | ||
137 | |||
138 | //Ensure we find the thread leader | ||
139 | { | ||
140 | auto job = Store::fetchAll<Mail>(query) | ||
141 | .syncThen<void, QList<Mail::Ptr>>([=, &threadLeader](const QList<Mail::Ptr> &mails) { | ||
142 | QCOMPARE(mails.size(), 1); | ||
143 | auto mail = *mails.first(); | ||
144 | threadLeader = mail; | ||
145 | QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1")); | ||
146 | }); | ||
147 | VERIFYEXEC(job); | ||
148 | } | ||
149 | |||
150 | //Ensure we find the thread leader still | ||
136 | { | 151 | { |
137 | auto job = Store::fetchAll<Mail>(query) | 152 | auto job = Store::fetchAll<Mail>(query) |
138 | .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { | 153 | .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { |
@@ -149,17 +164,24 @@ void MailThreadTest::testIndexInMixedOrder() | |||
149 | mail.setFolder(folder); | 164 | mail.setFolder(folder); |
150 | VERIFYEXEC(Store::create(mail)); | 165 | VERIFYEXEC(Store::create(mail)); |
151 | } | 166 | } |
152 | |||
153 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); | 167 | VERIFYEXEC(ResourceControl::flushMessageQueue(QByteArrayList() << mResourceInstanceIdentifier)); |
168 | |||
169 | //Ensure the thread is complete | ||
154 | { | 170 | { |
171 | Sink::Query query; | ||
172 | query.resources << mResourceInstanceIdentifier; | ||
173 | query.request<Mail::Subject>().request<Mail::MimeMessage>().request<Mail::Folder>().request<Mail::Date>(); | ||
174 | query.bloomThread = true; | ||
175 | query.sort<Mail::Date>(); | ||
176 | query.ids << threadLeader.identifier(); | ||
177 | |||
155 | auto job = Store::fetchAll<Mail>(query) | 178 | auto job = Store::fetchAll<Mail>(query) |
156 | .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { | 179 | .syncThen<void, QList<Mail::Ptr>>([=](const QList<Mail::Ptr> &mails) { |
157 | QCOMPARE(mails.size(), 1); | 180 | QCOMPARE(mails.size(), 2); |
158 | auto mail = *mails.first(); | 181 | auto mail = *mails.first(); |
159 | QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1")); | 182 | QCOMPARE(mail.getSubject(), QString::fromLatin1("Re: Re: 1")); |
160 | }); | 183 | }); |
161 | VERIFYEXEC(job); | 184 | VERIFYEXEC(job); |
162 | //TODO ensure we also find message 1 as part of thread. | ||
163 | } | 185 | } |
164 | 186 | ||
165 | /* VERIFYEXEC(Store::remove(mail)); */ | 187 | /* VERIFYEXEC(Store::remove(mail)); */ |