mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Heavier use of feature caching for fully populated caches
When a feature cache is set to "FullCache" mode, it will answer requests from this cache instead of querying the backend. Some more documentation for writing custom feature iterators based on QgsAbstractFeatureIterator Fix #9099
This commit is contained in:
parent
9d8d3cff08
commit
584aba7672
@ -24,19 +24,39 @@ QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache
|
||||
mFeatureIdIterator = featureIds.begin();
|
||||
}
|
||||
|
||||
QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache, QgsFeatureRequest featureRequest )
|
||||
: QgsAbstractFeatureIterator( featureRequest )
|
||||
, mVectorLayerCache( vlCache )
|
||||
{
|
||||
switch ( featureRequest.filterType() )
|
||||
{
|
||||
case QgsFeatureRequest::FilterFids:
|
||||
mFeatureIds = featureRequest.filterFids();
|
||||
break;
|
||||
|
||||
case QgsFeatureRequest::FilterFid:
|
||||
mFeatureIds = QgsFeatureIds() << featureRequest.filterFid();
|
||||
break;
|
||||
|
||||
default:
|
||||
mFeatureIds = mVectorLayerCache->mCache.keys().toSet();
|
||||
break;
|
||||
}
|
||||
|
||||
mFeatureIdIterator = mFeatureIds.begin();
|
||||
}
|
||||
|
||||
bool QgsCachedFeatureIterator::fetchFeature( QgsFeature& f )
|
||||
{
|
||||
mFeatureIdIterator++;
|
||||
|
||||
if ( mFeatureIdIterator == mFeatureIds.end() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
while ( mFeatureIdIterator != mFeatureIds.end() )
|
||||
{
|
||||
f = QgsFeature( *mVectorLayerCache->mCache[*mFeatureIdIterator]->feature() );
|
||||
return true;
|
||||
if ( mRequest.acceptFeature( f ) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QgsCachedFeatureIterator::rewind()
|
||||
|
@ -30,38 +30,60 @@ class CORE_EXPORT QgsCachedFeatureIterator : public QgsAbstractFeatureIterator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief
|
||||
* This constructor creates a feature iterator, that delivers only cached information, based on the
|
||||
* @link QgsFeatureIds @endlink. No request is made to the backend.
|
||||
*
|
||||
* @param vlCache The vector layer cache to use
|
||||
* @param featureRequest The feature request to answer
|
||||
* @param featureIds The feature ids to return
|
||||
*
|
||||
* @deprecated Use QgsCachedFeatureIterator( QgsVectorLayerCache* vlCache, QgsFeatureRequest featureRequest )
|
||||
* instead
|
||||
*/
|
||||
QgsCachedFeatureIterator( QgsVectorLayerCache* vlCache, QgsFeatureRequest featureRequest, QgsFeatureIds featureIds );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* This constructor creates a feature iterator, that delivers all cached features. No request is made to the backend.
|
||||
*
|
||||
* @param f
|
||||
* @return bool
|
||||
* @param vlCache The vector layer cache to use
|
||||
* @param featureRequest The feature request to answer
|
||||
*/
|
||||
virtual bool fetchFeature( QgsFeature& f );
|
||||
QgsCachedFeatureIterator( QgsVectorLayerCache* vlCache, QgsFeatureRequest featureRequest );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Rewind to the beginning of the iterator
|
||||
*
|
||||
* @return bool
|
||||
* @return bool true if the operation was ok
|
||||
*/
|
||||
virtual bool rewind();
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Close this iterator. No further features will be available.
|
||||
*
|
||||
* @return bool
|
||||
* @return true if successful
|
||||
*/
|
||||
virtual bool close();
|
||||
|
||||
// QgsAbstractFeatureIterator interface
|
||||
protected:
|
||||
/**
|
||||
* Implementation for fetching a feature.
|
||||
*
|
||||
* @param f Will write to this feature
|
||||
* @return bool true if the operation was ok
|
||||
*
|
||||
* @see bool getFeature( QgsFeature& f )
|
||||
*/
|
||||
virtual bool fetchFeature( QgsFeature& f );
|
||||
|
||||
/**
|
||||
* We have a local special iterator for FilterFids, no need to run the generic.
|
||||
*
|
||||
* @param f Will write to this feature
|
||||
* @return bool true if the operation was ok
|
||||
*/
|
||||
virtual bool nextFeatureFilterFids( QgsFeature& f ) { return fetchFeature( f ); }
|
||||
|
||||
private:
|
||||
QgsFeatureIds mFeatureIds;
|
||||
QgsVectorLayerCache* mVectorLayerCache;
|
||||
@ -77,7 +99,6 @@ class CORE_EXPORT QgsCachedFeatureWriterIterator : public QgsAbstractFeatureIter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief
|
||||
* This constructor creates a feature iterator, which queries the backend and caches retrieved features.
|
||||
*
|
||||
* @param vlCache The vector layer cache to use
|
||||
@ -86,27 +107,31 @@ class CORE_EXPORT QgsCachedFeatureWriterIterator : public QgsAbstractFeatureIter
|
||||
QgsCachedFeatureWriterIterator( QgsVectorLayerCache* vlCache, QgsFeatureRequest featureRequest );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Rewind to the beginning of the iterator
|
||||
*
|
||||
* @param f
|
||||
* @return bool
|
||||
*/
|
||||
virtual bool fetchFeature( QgsFeature& f );
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @return bool
|
||||
* @return bool true if the operation was ok
|
||||
*/
|
||||
virtual bool rewind();
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Close this iterator. No further features will be available.
|
||||
*
|
||||
* @return bool
|
||||
* @return true if successful
|
||||
*/
|
||||
virtual bool close();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Implementation for fetching a feature.
|
||||
*
|
||||
* @param f Will write to this feature
|
||||
* @return bool true if the operation was ok
|
||||
*
|
||||
* @see bool getFeature( QgsFeature& f )
|
||||
*/
|
||||
virtual bool fetchFeature( QgsFeature& f );
|
||||
|
||||
private:
|
||||
QgsFeatureIterator mFeatIt;
|
||||
QgsVectorLayerCache* mVectorLayerCache;
|
||||
|
@ -46,9 +46,7 @@ bool QgsCacheIndexFeatureId::getCacheIterator( QgsFeatureIterator &featureIterat
|
||||
{
|
||||
if ( C->isFidCached( featureRequest.filterFid() ) )
|
||||
{
|
||||
QgsFeatureIds fids;
|
||||
fids << featureRequest.filterFid();
|
||||
featureIterator = QgsFeatureIterator( new QgsCachedFeatureIterator( C, featureRequest, fids ) );
|
||||
featureIterator = QgsFeatureIterator( new QgsCachedFeatureIterator( C, featureRequest ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -39,21 +39,51 @@ class CORE_EXPORT QgsAbstractFeatureIterator
|
||||
//! end of iterating: free the resources / lock
|
||||
virtual bool close() = 0;
|
||||
|
||||
protected:
|
||||
virtual bool nextFeatureFilterExpression( QgsFeature &f );
|
||||
|
||||
virtual bool nextFeatureFilterFids( QgsFeature & f );
|
||||
|
||||
protected:
|
||||
/**
|
||||
* If you write a feature iterator for your provider, this is the method you
|
||||
* need to implement!!
|
||||
*
|
||||
* @param f The feature to write to
|
||||
* @return true if a feature was written to f
|
||||
*/
|
||||
virtual bool fetchFeature( QgsFeature& f ) = 0;
|
||||
|
||||
/**
|
||||
* By default, the iterator will fetch all features and check if the feature
|
||||
* matches the expression.
|
||||
* If you have a more sophisticated metodology (SQL request for the features...)
|
||||
* and you check for the expression in your fetchFeature method, you can just
|
||||
* redirect this call to fetchFeature so the default check will be omitted.
|
||||
*
|
||||
* @param f The feature to write to
|
||||
* @return true if a feature was written to f
|
||||
*/
|
||||
virtual bool nextFeatureFilterExpression( QgsFeature &f );
|
||||
|
||||
/**
|
||||
* By default, the iterator will fetch all features and check if the id
|
||||
* is in the request.
|
||||
* If you have a more sophisticated metodology (SQL request for the features...)
|
||||
* and you are sure, that any feature you return from fetchFeature will match
|
||||
* if the request was FilterFids you can just redirect this call to fetchFeature
|
||||
* so the default check will be omitted.
|
||||
*
|
||||
* @param f The feature to write to
|
||||
* @return true if a feature was written to f
|
||||
*/
|
||||
virtual bool nextFeatureFilterFids( QgsFeature & f );
|
||||
|
||||
/** A copy of the feature request. */
|
||||
QgsFeatureRequest mRequest;
|
||||
|
||||
/** Set to true, as soon as the iterator is closed. */
|
||||
bool mClosed;
|
||||
|
||||
// reference counting (to allow seamless copying of QgsFeatureIterator instances)
|
||||
//! reference counting (to allow seamless copying of QgsFeatureIterator instances)
|
||||
int refs;
|
||||
void ref(); // add reference
|
||||
void deref(); // remove reference, delete if refs == 0
|
||||
void ref(); //!< add reference
|
||||
void deref(); //!< remove reference, delete if refs == 0
|
||||
friend class QgsFeatureIterator;
|
||||
};
|
||||
|
||||
|
@ -76,9 +76,9 @@ void QgsVectorLayerCache::setFullCache( bool fullCache )
|
||||
setCacheSize( mLayer->featureCount() + 100 );
|
||||
|
||||
// Initialize the cache...
|
||||
QgsFeatureIterator it = getFeatures( QgsFeatureRequest()
|
||||
.setSubsetOfAttributes( mCachedAttributes )
|
||||
.setFlags( !mCacheGeometry ? QgsFeatureRequest::NoGeometry : QgsFeatureRequest::Flags( 0 ) ) );
|
||||
QgsFeatureIterator it ( new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest()
|
||||
.setSubsetOfAttributes( mCachedAttributes )
|
||||
.setFlags( !mCacheGeometry ? QgsFeatureRequest::NoGeometry : QgsFeatureRequest::Flags( 0 ) ) ) );
|
||||
|
||||
int i = 0;
|
||||
|
||||
@ -258,13 +258,22 @@ QgsFeatureIterator QgsVectorLayerCache::getFeatures( const QgsFeatureRequest &fe
|
||||
|
||||
if ( checkInformationCovered( featureRequest ) )
|
||||
{
|
||||
// Check if an index is able to deliver the requested features
|
||||
foreach ( QgsAbstractCacheIndex *idx, mCacheIndices )
|
||||
// If we have a full cache available, run on this
|
||||
if ( mFullCache )
|
||||
{
|
||||
if ( idx->getCacheIterator( it, featureRequest ) )
|
||||
it = QgsFeatureIterator( new QgsCachedFeatureIterator( this, featureRequest ) );
|
||||
requiresWriterIt = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if an index is able to deliver the requested features
|
||||
foreach ( QgsAbstractCacheIndex *idx, mCacheIndices )
|
||||
{
|
||||
requiresWriterIt = false;
|
||||
break;
|
||||
if ( idx->getCacheIterator( it, featureRequest ) )
|
||||
{
|
||||
requiresWriterIt = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user