diff options
-rw-r--r-- | common/datastorequery.cpp | 14 | ||||
-rw-r--r-- | common/datastorequery.h | 4 | ||||
-rw-r--r-- | tests/mailquerybenchmark.cpp | 9 |
3 files changed, 22 insertions, 5 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp index f3d9415..f5152b7 100644 --- a/common/datastorequery.cpp +++ b/common/datastorequery.cpp | |||
@@ -208,6 +208,7 @@ public: | |||
208 | }; | 208 | }; |
209 | 209 | ||
210 | QSet<QByteArray> mReducedValues; | 210 | QSet<QByteArray> mReducedValues; |
211 | QSet<QByteArray> mIncrementallyReducedValues; | ||
211 | QHash<QByteArray, QByteArray> mSelectedValues; | 212 | QHash<QByteArray, QByteArray> mSelectedValues; |
212 | QByteArray mReductionProperty; | 213 | QByteArray mReductionProperty; |
213 | QByteArray mSelectionProperty; | 214 | QByteArray mSelectionProperty; |
@@ -225,6 +226,11 @@ public: | |||
225 | 226 | ||
226 | virtual ~Reduce(){} | 227 | virtual ~Reduce(){} |
227 | 228 | ||
229 | void updateComplete() Q_DECL_OVERRIDE | ||
230 | { | ||
231 | mIncrementallyReducedValues.clear(); | ||
232 | } | ||
233 | |||
228 | static QByteArray getByteArray(const QVariant &value) { | 234 | static QByteArray getByteArray(const QVariant &value) { |
229 | if (value.type() == QVariant::DateTime) { | 235 | if (value.type() == QVariant::DateTime) { |
230 | return value.toDateTime().toString().toLatin1(); | 236 | return value.toDateTime().toString().toLatin1(); |
@@ -304,7 +310,8 @@ public: | |||
304 | //During initial query, do nothing. The lookup above will take care of it. | 310 | //During initial query, do nothing. The lookup above will take care of it. |
305 | //During updates adjust the reduction according to the modification/addition or removal | 311 | //During updates adjust the reduction according to the modification/addition or removal |
306 | //We have to redo the reduction for every element, because of the aggregation values. | 312 | //We have to redo the reduction for every element, because of the aggregation values. |
307 | if (mIncremental) { | 313 | if (mIncremental && !mIncrementallyReducedValues.contains(reductionValueBa)) { |
314 | mIncrementallyReducedValues.insert(reductionValueBa); | ||
308 | //Redo the reduction to find new aggregated values | 315 | //Redo the reduction to find new aggregated values |
309 | QMap<QByteArray, QVariant> aggregateValues; | 316 | QMap<QByteArray, QVariant> aggregateValues; |
310 | auto selectionResult = reduceOnValue(reductionValue, aggregateValues); | 317 | auto selectionResult = reduceOnValue(reductionValue, aggregateValues); |
@@ -621,6 +628,11 @@ ResultSet DataStoreQuery::update(qint64 baseRevision) | |||
621 | void DataStoreQuery::updateComplete() | 628 | void DataStoreQuery::updateComplete() |
622 | { | 629 | { |
623 | mSource->mIncrementalIds.clear(); | 630 | mSource->mIncrementalIds.clear(); |
631 | auto source = mCollector; | ||
632 | while (source) { | ||
633 | source->updateComplete(); | ||
634 | source = source->mSource; | ||
635 | } | ||
624 | } | 636 | } |
625 | 637 | ||
626 | ResultSet DataStoreQuery::execute() | 638 | ResultSet DataStoreQuery::execute() |
diff --git a/common/datastorequery.h b/common/datastorequery.h index de4ae26..cc501e6 100644 --- a/common/datastorequery.h +++ b/common/datastorequery.h | |||
@@ -107,11 +107,13 @@ public: | |||
107 | return mDatastore->indexLookup(property, value); | 107 | return mDatastore->indexLookup(property, value); |
108 | } | 108 | } |
109 | 109 | ||
110 | virtual void skip() { mSource->skip(); }; | 110 | virtual void skip() { mSource->skip(); } |
111 | 111 | ||
112 | //Returns true for as long as a result is available | 112 | //Returns true for as long as a result is available |
113 | virtual bool next(const std::function<void(const ResultSet::Result &)> &callback) = 0; | 113 | virtual bool next(const std::function<void(const ResultSet::Result &)> &callback) = 0; |
114 | 114 | ||
115 | virtual void updateComplete() { } | ||
116 | |||
115 | FilterBase::Ptr mSource; | 117 | FilterBase::Ptr mSource; |
116 | DataStoreQuery *mDatastore; | 118 | DataStoreQuery *mDatastore; |
117 | bool mIncremental = false; | 119 | bool mIncremental = false; |
diff --git a/tests/mailquerybenchmark.cpp b/tests/mailquerybenchmark.cpp index ca1e026..402f31f 100644 --- a/tests/mailquerybenchmark.cpp +++ b/tests/mailquerybenchmark.cpp | |||
@@ -219,11 +219,14 @@ private slots: | |||
219 | 219 | ||
220 | populateDatabase(count, 10, false, count); | 220 | populateDatabase(count, 10, false, count); |
221 | time.restart(); | 221 | time.restart(); |
222 | context.mResourceAccess->revisionChanged(2000); | 222 | for (int i = 0; i <= 10; i++) { |
223 | //Simulate revision updates in steps of 100 | ||
224 | context.mResourceAccess->revisionChanged(1000 + i * 100); | ||
225 | } | ||
223 | //We should have 200 items in total in the end. 2000 mails / 10 folders => 200 reduced mails | 226 | //We should have 200 items in total in the end. 2000 mails / 10 folders => 200 reduced mails |
224 | QTRY_COMPARE(added.count(), 200); | 227 | QTRY_COMPARE(added.count(), 200); |
225 | //For every email we have to redo the reduction and increase the count, which is a modification. | 228 | //We get one modification per thread from the first 100 (1000 mails / 10 folders), everything else is optimized away because we ignore repeated updates to the same thread. |
226 | QTRY_COMPARE(modified.count(), 900); | 229 | QTRY_COMPARE(modified.count(), 100); |
227 | std::cout << "Incremental query took " << time.elapsed() << std::endl; | 230 | std::cout << "Incremental query took " << time.elapsed() << std::endl; |
228 | std::cout << "added " << added.count() << std::endl; | 231 | std::cout << "added " << added.count() << std::endl; |
229 | std::cout << "modified " << modified.count() << std::endl; | 232 | std::cout << "modified " << modified.count() << std::endl; |