From afd5d1e9344f41a40f882fb204810f8e650813c0 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 10 Aug 2016 12:28:00 +1000 Subject: [PATCH] Recognise that a cache can be filled using a FilterNone request On behalf of Faunalia, sponsored by ENEL --- python/core/qgsvectorlayercache.sip | 9 ++++ src/core/qgsvectorlayercache.cpp | 4 ++ src/core/qgsvectorlayercache.h | 9 ++++ tests/src/core/testqgsvectorlayercache.cpp | 48 ++++++++++++++++++++++ 4 files changed, 70 insertions(+) diff --git a/python/core/qgsvectorlayercache.sip b/python/core/qgsvectorlayercache.sip index 99a3fd196b6..3fe37c87f07 100644 --- a/python/core/qgsvectorlayercache.sip +++ b/python/core/qgsvectorlayercache.sip @@ -65,9 +65,18 @@ class QgsVectorLayerCache : QObject * be used for slow data sources, be aware, that the call to this method might take a long time. * * @param fullCache True: enable full caching, False: disable full caching + * @see hasFullCache() */ void setFullCache( bool fullCache ); + /** Returns true if the cache is complete, ie it contains all features. This may happen as + * a result of a call to setFullCache() or by through a feature request which resulted in + * all available features being cached. + * @see setFullCache() + * @note added in QGIS 3.0 + */ + bool hasFullCache() const; + /** * @brief * Adds a {@link QgsAbstractCacheIndex} to this cache. Cache indices know about features present diff --git a/src/core/qgsvectorlayercache.cpp b/src/core/qgsvectorlayercache.cpp index dd8e74ec70b..ffb067a4865 100644 --- a/src/core/qgsvectorlayercache.cpp +++ b/src/core/qgsvectorlayercache.cpp @@ -180,6 +180,10 @@ void QgsVectorLayerCache::requestCompleted( const QgsFeatureRequest& featureRequ { idx->requestCompleted( featureRequest, fids ); } + if ( featureRequest.filterType() == QgsFeatureRequest::FilterNone ) + { + mFullCache = true; + } } } diff --git a/src/core/qgsvectorlayercache.h b/src/core/qgsvectorlayercache.h index d7c766c63c6..c06127e118d 100644 --- a/src/core/qgsvectorlayercache.h +++ b/src/core/qgsvectorlayercache.h @@ -133,9 +133,18 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject * be used for slow data sources, be aware, that the call to this method might take a long time. * * @param fullCache True: enable full caching, False: disable full caching + * @see hasFullCache() */ void setFullCache( bool fullCache ); + /** Returns true if the cache is complete, ie it contains all features. This may happen as + * a result of a call to setFullCache() or by through a feature request which resulted in + * all available features being cached. + * @see setFullCache() + * @note added in QGIS 3.0 + */ + bool hasFullCache() const { return mFullCache; } + /** * @brief * Adds a {@link QgsAbstractCacheIndex} to this cache. Cache indices know about features present diff --git a/tests/src/core/testqgsvectorlayercache.cpp b/tests/src/core/testqgsvectorlayercache.cpp index 5cd564feb8a..f5d68ed258e 100644 --- a/tests/src/core/testqgsvectorlayercache.cpp +++ b/tests/src/core/testqgsvectorlayercache.cpp @@ -52,6 +52,8 @@ class TestVectorLayerCache : public QObject void testCacheAttrActions(); // Test attribute add/ attribute delete void testFeatureActions(); // Test adding/removing features works void testSubsetRequest(); + void testFullCache(); + void testFullCacheThroughRequest(); void onCommittedFeaturesAdded( const QString&, const QgsFeatureList& ); @@ -219,6 +221,52 @@ void TestVectorLayerCache::testSubsetRequest() QVERIFY( a == f.attribute( 3 ) ); } +void TestVectorLayerCache::testFullCache() +{ + // cache is too small to fit all features + QgsVectorLayerCache cache( mPointsLayer, 2 ); + QVERIFY( !cache.hasFullCache() ); + QVERIFY( cache.cacheSize() < mPointsLayer->featureCount() ); + // but we set it to full cache + cache.setFullCache( true ); + // so now it should have sufficient size for all features + QVERIFY( cache.cacheSize() >= mPointsLayer->featureCount() ); + QVERIFY( cache.hasFullCache() ); + + // double check that everything is indeed in the cache + QgsFeatureIterator it = mPointsLayer->getFeatures(); + QgsFeature f; + while ( it.nextFeature( f ) ) + { + QVERIFY( cache.isFidCached( f.id() ) ); + } +} + +void TestVectorLayerCache::testFullCacheThroughRequest() +{ + // make sure cache is sufficient size for all features + QgsVectorLayerCache cache( mPointsLayer, mPointsLayer->featureCount() * 2 ); + QVERIFY( !cache.hasFullCache() ); + + // now request all features from cache + QgsFeatureIterator it = cache.getFeatures( QgsFeatureRequest() ); + QgsFeature f; + while ( it.nextFeature( f ) ) + { + // suck in all features + } + + // cache should now contain all features + it = mPointsLayer->getFeatures(); + while ( it.nextFeature( f ) ) + { + QVERIFY( cache.isFidCached( f.id() ) ); + } + + // so it should be a full cache! + QVERIFY( cache.hasFullCache() ); +} + void TestVectorLayerCache::onCommittedFeaturesAdded( const QString& layerId, const QgsFeatureList& features ) { Q_UNUSED( layerId )