From 1240a482ab13d285d2624c33015f0f61f16d91a9 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 12 Feb 2016 17:55:44 +0100 Subject: Prepare query sorting --- common/queryrunner.cpp | 62 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 21 deletions(-) (limited to 'common/queryrunner.cpp') diff --git a/common/queryrunner.cpp b/common/queryrunner.cpp index b6f5b51..fde5b04 100644 --- a/common/queryrunner.cpp +++ b/common/queryrunner.cpp @@ -55,7 +55,7 @@ private: ResultSet loadInitialResultSet(const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet &remainingFilters); ResultSet loadIncrementalResultSet(qint64 baseRevision, const Sink::Query &query, Sink::Storage::Transaction &transaction, QSet &remainingFilters); - ResultSet filterSet(const ResultSet &resultSet, const std::function &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery); + ResultSet filterAndSortSet(ResultSet &resultSet, const std::function &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery, const QByteArray &sortProperty); std::function getFilter(const QSet remainingFilters, const Sink::Query &query); qint64 load(const Sink::Query &query, const std::function &)> &baseSetRetriever, Sink::ResultProviderInterface &resultProvider, bool initialQuery); @@ -272,33 +272,53 @@ ResultSet QueryWorker::loadIncrementalResultSet(qint64 baseRevision, } template -ResultSet QueryWorker::filterSet(const ResultSet &resultSet, const std::function &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery) +ResultSet QueryWorker::filterAndSortSet(ResultSet &resultSet, const std::function &filter, const Sink::Storage::NamedDatabase &db, bool initialQuery, const QByteArray &sortProperty) { - auto resultSetPtr = QSharedPointer::create(resultSet); + auto sortedMap = QSharedPointer>::create(); - //Read through the source values and return whatever matches the filter - std::function)> generator = [this, resultSetPtr, &db, filter, initialQuery](std::function callback) -> bool { - if (resultSetPtr->next()) { + if (initialQuery) { + while (resultSet.next()) { //readEntity is only necessary if we actually want to filter or know the operation type (but not a big deal if we do it always I guess) - readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) { - //Always remove removals, they probably don't match due to non-available properties - if (filter(domainObject) || operation == Sink::Operation_Removal) { - if (initialQuery) { - //We're not interested in removals during the initial query - if (operation != Sink::Operation_Removal) { - callback(domainObject, Sink::Operation_Creation); - } + readEntity(db, resultSet.id(), [this, filter, initialQuery, sortedMap, sortProperty, &resultSet](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) { + //We're not interested in removals during the initial query + if ((operation != Sink::Operation_Removal) && filter(domainObject)) { + if (!sortProperty.isEmpty()) { + sortedMap->insert(domainObject->getProperty(sortProperty).toString().toLatin1(), domainObject->identifier()); } else { - callback(domainObject, operation); + sortedMap->insert(domainObject->identifier(), domainObject->identifier()); } } }); - return true; - } else { - return false; } - }; - return ResultSet(generator); + + auto iterator = QSharedPointer >::create(*sortedMap); + ResultSet::ValueGenerator generator = [this, iterator, sortedMap, &db, filter, initialQuery](std::function callback) -> bool { + if (iterator->hasNext()) { + readEntity(db, iterator->next().value(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) { + callback(domainObject, Sink::Operation_Creation); + }); + return true; + } + return false; + }; + return ResultSet(generator); + } else { + auto resultSetPtr = QSharedPointer::create(resultSet); + ResultSet::ValueGenerator generator = [this, resultSetPtr, &db, filter, initialQuery](std::function callback) -> bool { + if (resultSetPtr->next()) { + //readEntity is only necessary if we actually want to filter or know the operation type (but not a big deal if we do it always I guess) + readEntity(db, resultSetPtr->id(), [this, filter, callback, initialQuery](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &domainObject, Sink::Operation operation) { + //Always remove removals, they probably don't match due to non-available properties + if ((operation == Sink::Operation_Removal) || filter(domainObject)) { + callback(domainObject, operation); + } + }); + return true; + } + return false; + }; + return ResultSet(generator); + } } template @@ -342,7 +362,7 @@ qint64 QueryWorker::load(const Sink::Query &query, const std::functi QSet remainingFilters; auto resultSet = baseSetRetriever(transaction, remainingFilters); Trace() << "Base set retrieved. " << time.elapsed(); - auto filteredSet = filterSet(resultSet, getFilter(remainingFilters, query), db, initialQuery); + auto filteredSet = filterAndSortSet(resultSet, getFilter(remainingFilters, query), db, initialQuery, query.sortProperty); Trace() << "Filtered set retrieved. " << time.elapsed(); replaySet(filteredSet, resultProvider, query.requestedProperties); Trace() << "Filtered set replayed. " << time.elapsed(); -- cgit v1.2.3