Skip to content
Permalink
Browse files

Clear existing cache when QgsVectorLayerCache is set to cache geom

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 307daf1e581361e2a3445fffeb0f06bfeff0d118
Showing with 53 additions and 1 deletion.
  1. +7 −1 src/core/qgsvectorlayercache.cpp
  2. +46 −0 tests/src/core/testqgsvectorlayercache.cpp
@@ -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& ) ) );
@@ -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 )
@@ -54,6 +54,7 @@ class TestVectorLayerCache : public QObject
void testFullCache();
void testFullCacheThroughRequest();
void testCanUseCacheForRequest();
void testCacheGeom();

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

@@ -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 )

0 comments on commit 307daf1

Please sign in to comment.
You can’t perform that action at this time.