From 5562b0551a62d60e5cfde4e7fec166f73e06d660 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sat, 25 Jul 2015 17:00:50 +0200 Subject: Only query for new revisions. Instead of clearing the result everytime we only query for the stuff that has changed. --- common/facade.h | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'common') diff --git a/common/facade.h b/common/facade.h index b68b42e..9222e26 100644 --- a/common/facade.h +++ b/common/facade.h @@ -58,7 +58,10 @@ public: KAsync::Job run(qint64 newRevision = 0) { //TODO: JOBAPI: that last empty .then should not be necessary - return queryFunction(mLatestRevision, newRevision).then([this](qint64 revision) { + if (mLatestRevision == newRevision && mLatestRevision > 0) { + return KAsync::null(); + } + return queryFunction(mLatestRevision + 1, newRevision).then([this](qint64 revision) { mLatestRevision = revision; }).then([](){}); } @@ -280,7 +283,7 @@ protected: }); } - static void readValue(const QSharedPointer &storage, const QByteArray &key, const std::function &resultCallback, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory) + static void readValue(const QSharedPointer &storage, const QByteArray &key, const std::function &resultCallback, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory, const QByteArray &instanceIdentifier) { scan(storage, key, [=](const QByteArray &key, const Akonadi2::Entity &entity) { const auto metadataBuffer = Akonadi2::EntityBuffer::readBuffer(entity.metadata()); @@ -289,7 +292,7 @@ protected: //Not i.e. for tags that are stored as flags in each entity of an imap store. //additional properties that don't have a 1:1 mapping (such as separately stored tags), //could be added to the adaptor - auto domainObject = QSharedPointer::create(mResourceInstanceIdentifier, key, revision, adaptorFactory->createAdaptor(entity)); + auto domainObject = QSharedPointer::create(instanceIdentifier, key, revision, adaptorFactory->createAdaptor(entity)); resultCallback(domainObject); return true; }); @@ -307,25 +310,25 @@ protected: return ResultSet(keys); } - static ResultSet filteredSet(const ResultSet &resultSet, const std::function &filter, const QSharedPointer &storage, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory) + static ResultSet filteredSet(const ResultSet &resultSet, const std::function &filter, const QSharedPointer &storage, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory, qint64 baseRevision, qint64 topRevision, const QByteArray &instanceIdentifier) { auto resultSetPtr = QSharedPointer::create(resultSet); //Read through the source values and return whatever matches the filter - std::function)> generator = [resultSetPtr, storage, adaptorFactory, filter](std::function callback) -> bool { + std::function)> generator = [resultSetPtr, storage, adaptorFactory, filter, instanceIdentifier](std::function callback) -> bool { while (resultSetPtr->next()) { readValue(storage, resultSetPtr->id(), [filter, callback](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &domainObject) { if (filter(domainObject)) { callback(domainObject); } - }, adaptorFactory); + }, adaptorFactory, instanceIdentifier); } return false; }; return ResultSet(generator); } - static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer &storage, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory, const QByteArray &resourceInstanceIdentifier) + static ResultSet getResultSet(const Akonadi2::Query &query, const QSharedPointer &storage, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory, const QByteArray &resourceInstanceIdentifier, qint64 baseRevision, qint64 topRevision) { QSet appliedFilters; ResultSet resultSet = Akonadi2::ApplicationDomain::TypeImplementation::queryIndexes(query, resourceInstanceIdentifier, appliedFilters); @@ -336,7 +339,12 @@ protected: resultSet = fullScan(storage); } - auto filter = [remainingFilters, query](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &domainObject) -> bool { + auto filter = [remainingFilters, query, baseRevision, topRevision](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &domainObject) -> bool { + if (topRevision > 0) { + if (domainObject->revision() < baseRevision || domainObject->revision() > topRevision) { + return false; + } + } for (const auto &filterProperty : remainingFilters) { //TODO implement other comparison operators than equality if (domainObject->getProperty(filterProperty) != query.propertyFilter.value(filterProperty)) { @@ -346,7 +354,7 @@ protected: return true; }; - return filteredSet(resultSet, filter, storage, adaptorFactory); + return filteredSet(resultSet, filter, storage, adaptorFactory, baseRevision, topRevision, resourceInstanceIdentifier); } virtual KAsync::Job load(const Akonadi2::Query &query, const QSharedPointer > &resultProvider, qint64 oldRevision, qint64 newRevision) @@ -359,19 +367,15 @@ protected: storage->startTransaction(Akonadi2::Storage::ReadOnly); //TODO start transaction on indexes as well - const qint64 revision = storage->maxRevision(); - - auto resultSet = getResultSet(query, storage, mDomainTypeAdaptorFactory, mResourceInstanceIdentifier); - // TODO only emit changes and don't replace everything - resultProvider->clear(); + auto resultSet = getResultSet(query, storage, mDomainTypeAdaptorFactory, mResourceInstanceIdentifier, oldRevision, newRevision); auto resultCallback = std::bind(&Akonadi2::ResultProvider::add, resultProvider, std::placeholders::_1); while(resultSet.next([resultCallback](const Akonadi2::ApplicationDomain::ApplicationDomainType::Ptr &value) -> bool { resultCallback(Akonadi2::ApplicationDomain::ApplicationDomainType::getInMemoryRepresentation(*value)); return true; })){}; storage->abortTransaction(); - return revision; + return newRevision; }); } -- cgit v1.2.3