Skip to content

Commit

Permalink
Clear existing cache when QgsVectorLayerCache is set to cache geom
Browse files Browse the repository at this point in the history
Any features inside the cache must be cleared, because they
won't necessarily have the feature's geometry cached

On behalf of Faunalia, sponsored by ENEL
  • Loading branch information
nyalldawson committed Mar 5, 2017
1 parent f0d2f6d commit 11c4444
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/core/qgsvectorlayercache.cpp
Expand Up @@ -58,7 +58,9 @@ int QgsVectorLayerCache::cacheSize()

void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
{
mCacheGeometry = cacheGeometry && mLayer->hasGeometryType();
bool shouldCache = cacheGeometry && mLayer->hasGeometryType();
bool mustInvalidate = shouldCache && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
mCacheGeometry = shouldCache;
if ( cacheGeometry )
{
connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
Expand All @@ -67,6 +69,10 @@ void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
{
disconnect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsVectorLayerCache::geometryChanged );
}
if ( mustInvalidate )
{
invalidate();
}
}

void QgsVectorLayerCache::setCacheSubsetOfAttributes( const QgsAttributeList &attributes )
Expand Down
46 changes: 46 additions & 0 deletions tests/src/core/testqgsvectorlayercache.cpp
Expand Up @@ -55,6 +55,7 @@ class TestVectorLayerCache : public QObject
void testFullCache();
void testFullCacheThroughRequest();
void testCanUseCacheForRequest();
void testCacheGeom();

void onCommittedFeaturesAdded( const QString &, const QgsFeatureList & );

Expand Down Expand Up @@ -331,6 +332,51 @@ void TestVectorLayerCache::testCanUseCacheForRequest()
QVERIFY( cache.canUseCacheForRequest( QgsFeatureRequest().setFilterExpression( "$x<5" ), it ) );
}

void TestVectorLayerCache::testCacheGeom()
{
QgsVectorLayerCache cache( mPointsLayer, 2 );
// cache geometry
cache.setCacheGeometry( true );

//first get some feature ids from layer
QgsFeature f;
QgsFeatureIterator it = mPointsLayer->getFeatures();
it.nextFeature( f );
QgsFeatureId id1 = f.id();
it.nextFeature( f );
QgsFeatureId id2 = f.id();

QgsFeatureRequest req;
req.setFlags( QgsFeatureRequest::NoGeometry ); // should be ignored by cache
req.setFilterFids( QgsFeatureIds() << id1 << id2 );

it = cache.getFeatures( req );
while ( it.nextFeature( f ) )
{
QVERIFY( f.hasGeometry() );
}

// disabled geometry caching
cache.setCacheGeometry( false );
// we should still have cached features... no need to lose these!
QCOMPARE( cache.cachedFeatureIds(), QgsFeatureIds() << id1 << id2 );
it = cache.getFeatures( req );
while ( it.nextFeature( f ) )
{
QVERIFY( f.hasGeometry() );
}

// now upgrade cache from no geometry -> geometry, should be cleared since we
// cannot be confident that features existing in the cache have geometry
cache.setCacheGeometry( true );
QVERIFY( cache.cachedFeatureIds().isEmpty() );
it = cache.getFeatures( req );
while ( it.nextFeature( f ) )
{
QVERIFY( f.hasGeometry() );
}
}

void TestVectorLayerCache::onCommittedFeaturesAdded( const QString &layerId, const QgsFeatureList &features )
{
Q_UNUSED( layerId )
Expand Down

0 comments on commit 11c4444

Please sign in to comment.