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

(cherry-picked from 11c444)
  • Loading branch information
nyalldawson committed Mar 7, 2017
1 parent 2a6bceb commit 307daf1
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
Original file line number Diff line number Diff line change
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, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), SLOT( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
Expand All @@ -67,6 +69,10 @@ void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
{
disconnect( mLayer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SLOT( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
}
if ( mustInvalidate )
{
invalidate();
}
}

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

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

Expand Down Expand Up @@ -330,6 +331,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.constGeometry() );
}

// 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.constGeometry() );
}

// 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.constGeometry() );
}
}

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

0 comments on commit 307daf1

Please sign in to comment.