Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update of providers' feature iterators
Currently providers do not support concurrent access of more iterators at once, so keep pointer to the currently active iterator and auto-close previous iterator when a new one is requested.
Auto-close iterators when all features have been set.
Auto-close iterators when the provider is deleted.
  • Loading branch information
wonder-sk committed Jan 16, 2013
1 parent de3f07e commit a6c5fd8
Show file tree
Hide file tree
Showing 23 changed files with 136 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.h
Expand Up @@ -1084,7 +1084,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
//annotation form for this layer
QString mAnnotationForm;

QgsFeatureIterator mLayerIterator; // temporary
QgsFeatureIterator mLayerIterator; // temporary: to support old API
friend class QgsVectorLayerFeatureIterator;
#if 0
bool mFetching;
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -108,6 +108,7 @@ bool QgsVectorLayerFeatureIterator::nextFeature( QgsFeature& f )
return true;
}

close();
return false;
}

Expand Down
Expand Up @@ -9,6 +9,11 @@
QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTextProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
P->mActiveIterator->close();
P->mActiveIterator = this;

rewind();
}

Expand Down Expand Up @@ -93,6 +98,7 @@ bool QgsDelimitedTextFeatureIterator::nextFeature( QgsFeature& feature )
// loaded, display them now.
P->handleInvalidLines();

close();
return false;
}

Expand All @@ -117,6 +123,9 @@ bool QgsDelimitedTextFeatureIterator::close()
if ( mClosed )
return false;

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
Expand Down
4 changes: 4 additions & 0 deletions src/providers/delimitedtext/qgsdelimitedtextprovider.cpp
Expand Up @@ -148,6 +148,7 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
, mShowInvalidLines( false )
, mCrs()
, mWkbType( QGis::WKBUnknown )
, mActiveIterator( 0 )
{
QUrl url = QUrl::fromEncoded( uri.toAscii() );

Expand Down Expand Up @@ -449,6 +450,9 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )

QgsDelimitedTextProvider::~QgsDelimitedTextProvider()
{
if ( mActiveIterator )
mActiveIterator->close();

if ( mFile )
mFile->close();
delete mFile;
Expand Down
1 change: 1 addition & 0 deletions src/providers/delimitedtext/qgsdelimitedtextprovider.h
Expand Up @@ -219,4 +219,5 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
QStringList splitLine( QString line ) { return splitLine( line, mDelimiterType, mDelimiter ); }

friend class QgsDelimitedTextFeatureIterator;
QgsDelimitedTextFeatureIterator* mActiveIterator;
};
13 changes: 12 additions & 1 deletion src/providers/gpx/qgsgpxfeatureiterator.cpp
Expand Up @@ -13,6 +13,11 @@
QgsGPXFeatureIterator::QgsGPXFeatureIterator( QgsGPXProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
P->mActiveIterator->close();
P->mActiveIterator = this;

rewind();
}

Expand Down Expand Up @@ -50,6 +55,9 @@ bool QgsGPXFeatureIterator::close()

// nothing to do

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
Expand All @@ -67,7 +75,9 @@ bool QgsGPXFeatureIterator::nextFeature( QgsFeature& feature )

if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
{
return readFid( feature );
bool res = readFid( feature );
close();
return res;
}


Expand Down Expand Up @@ -111,6 +121,7 @@ bool QgsGPXFeatureIterator::nextFeature( QgsFeature& feature )
}
}

close();
return false;
}

Expand Down
4 changes: 4 additions & 0 deletions src/providers/gpx/qgsgpxprovider.cpp
Expand Up @@ -66,6 +66,7 @@ const QString GPX_DESCRIPTION = QObject::tr( "GPS eXchange format provider" );

QgsGPXProvider::QgsGPXProvider( QString uri ) :
QgsVectorDataProvider( uri )
, mActiveIterator( 0 )
{
// assume that it won't work
mValid = false;
Expand Down Expand Up @@ -110,6 +111,9 @@ QgsGPXProvider::QgsGPXProvider( QString uri ) :

QgsGPXProvider::~QgsGPXProvider()
{
if ( mActiveIterator )
mActiveIterator->close();

QgsGPSData::releaseData( mFileName );
}

Expand Down
2 changes: 2 additions & 0 deletions src/providers/gpx/qgsgpxprovider.h
Expand Up @@ -28,6 +28,7 @@ class QFile;
class QDomDocument;
class QgsGPSData;

class QgsGPXFeatureIterator;

/**
\class QgsGPXProvider
Expand Down Expand Up @@ -171,4 +172,5 @@ class QgsGPXProvider : public QgsVectorDataProvider
wkbPoint mWKBpt;

friend class QgsGPXFeatureIterator;
QgsGPXFeatureIterator* mActiveIterator;
};
17 changes: 17 additions & 0 deletions src/providers/grass/qgsgrassfeatureiterator.cpp
Expand Up @@ -21,6 +21,11 @@ extern "C"
QgsGrassFeatureIterator::QgsGrassFeatureIterator( QgsGrassProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
P->mActiveIterator->close();
P->mActiveIterator = this;

// check if outdated and update if necessary
P->ensureUpdated();

Expand Down Expand Up @@ -127,10 +132,16 @@ bool QgsGrassFeatureIterator::nextFeature( QgsFeature& feature )
QgsDebugMsgLevel( "entered.", 3 );

if ( P->isEdited() || P->isFrozen() || !P->mValid )
{
close();
return false;
}

if ( P->mCidxFieldIndex < 0 || mNextCidx >= P->mCidxFieldNumCats )
{
close();
return false; // No features, no features in this layer
}

bool filterById = mRequest.filterType() == QgsFeatureRequest::FilterFid;

Expand All @@ -154,7 +165,10 @@ bool QgsGrassFeatureIterator::nextFeature( QgsFeature& feature )
break;
}
if ( !found )
{
close();
return false; // No more features
}
#if QGISDEBUG > 3
QgsDebugMsg( QString( "cat = %1 type = %2 id = %3" ).arg( cat ).arg( type ).arg( id ) );
#endif
Expand Down Expand Up @@ -209,6 +223,9 @@ bool QgsGrassFeatureIterator::close()

free( mSelection );

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
Expand Down
5 changes: 5 additions & 0 deletions src/providers/grass/qgsgrassprovider.cpp
Expand Up @@ -73,6 +73,7 @@ static QString GRASS_DESCRIPTION = "Grass provider"; // XXX verify this

QgsGrassProvider::QgsGrassProvider( QString uri )
: QgsVectorDataProvider( uri )
, mActiveIterator( 0 )
{
QgsDebugMsg( QString( "QgsGrassProvider URI: %1" ).arg( uri ) );

Expand Down Expand Up @@ -256,6 +257,10 @@ void QgsGrassProvider::update( void )
QgsGrassProvider::~QgsGrassProvider()
{
QgsDebugMsg( "entered." );

if ( mActiveIterator )
mActiveIterator->close();

closeLayer( mLayerId );
}

Expand Down
4 changes: 4 additions & 0 deletions src/providers/grass/qgsgrassprovider.h
Expand Up @@ -18,6 +18,9 @@

class QgsFeature;
class QgsField;

class QgsGrassFeatureIterator;

#include <QDateTime>

#include "qgsvectordataprovider.h"
Expand Down Expand Up @@ -638,6 +641,7 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
static std::vector<GMAP> mMaps; // Map

friend class QgsGrassFeatureIterator;
QgsGrassFeatureIterator* mActiveIterator;
};

#endif // QGSGRASSPROVIDER_H
13 changes: 13 additions & 0 deletions src/providers/memory/qgsmemoryfeatureiterator.cpp
Expand Up @@ -9,6 +9,11 @@
QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p ), mSelectRectGeom( NULL )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
P->mActiveIterator->close();
P->mActiveIterator = this;

if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
{
mSelectRectGeom = QgsGeometry::fromRect( request.filterRect() );
Expand Down Expand Up @@ -85,6 +90,9 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature& feature )
feature = P->mFeatures[*mFeatureIdListIterator];
mFeatureIdListIterator++;
}
else
close();

return hasFeature;
}

Expand Down Expand Up @@ -131,6 +139,8 @@ bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( QgsFeature& feature )
feature.setValid( true );
feature.setFields( &P->mFields ); // allow name-based attribute lookups
}
else
close();

return hasFeature;
}
Expand All @@ -156,6 +166,9 @@ bool QgsMemoryFeatureIterator::close()
delete mSelectRectGeom;
mSelectRectGeom = NULL;

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
8 changes: 6 additions & 2 deletions src/providers/memory/qgsmemoryprovider.cpp
Expand Up @@ -31,8 +31,9 @@ static const QString TEXT_PROVIDER_KEY = "memory";
static const QString TEXT_PROVIDER_DESCRIPTION = "Memory provider";

QgsMemoryProvider::QgsMemoryProvider( QString uri )
: QgsVectorDataProvider( uri ),
mSpatialIndex( NULL )
: QgsVectorDataProvider( uri )
, mSpatialIndex( NULL )
, mActiveIterator( 0 )
{
// Initialize the geometry with the uri to support old style uri's
// (ie, just 'point', 'line', 'polygon')
Expand Down Expand Up @@ -138,6 +139,9 @@ QgsMemoryProvider::QgsMemoryProvider( QString uri )

QgsMemoryProvider::~QgsMemoryProvider()
{
if ( mActiveIterator )
mActiveIterator->close();

delete mSpatialIndex;
}

Expand Down
3 changes: 3 additions & 0 deletions src/providers/memory/qgsmemoryprovider.h
Expand Up @@ -21,6 +21,8 @@ typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;

class QgsSpatialIndex;

class QgsMemoryFeatureIterator;

class QgsMemoryProvider : public QgsVectorDataProvider
{
Q_OBJECT
Expand Down Expand Up @@ -167,4 +169,5 @@ class QgsMemoryProvider : public QgsVectorDataProvider
QgsSpatialIndex* mSpatialIndex;

friend class QgsMemoryFeatureIterator;
QgsMemoryFeatureIterator* mActiveIterator;
};
22 changes: 14 additions & 8 deletions src/providers/ogr/qgsogrfeatureiterator.cpp
Expand Up @@ -19,6 +19,11 @@
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request )
: QgsAbstractFeatureIterator( request ), P( p )
{
// make sure that only one iterator is active
if ( P->mActiveIterator )
P->mActiveIterator->close();
P->mActiveIterator = this;

// set the selection rectangle pointer to 0
mSelectionRectangle = 0;

Expand Down Expand Up @@ -85,24 +90,24 @@ bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature )

if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
{
// make sure that only one next feature call returns a valid feature!
if ( mFeatureFetched )
return false;

OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) );
if ( !fet )
{
close();
return false;
}

// skip features without geometry
if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom )
{
OGR_F_Destroy( fet );
close();
return false;
}

readFeature( fet, feature );
feature.setValid( true );
mFeatureFetched = true;
close(); // the feature has been read: we have finished here
return true;
}

Expand Down Expand Up @@ -148,9 +153,7 @@ bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature )

QgsDebugMsg( "Feature is null" );

// probably should reset reading here
rewind();

close();
return false;
}

Expand All @@ -177,6 +180,9 @@ bool QgsOgrFeatureIterator::close()
mSelectionRectangle = 0;
}

// tell provider that this iterator is not active anymore
P->mActiveIterator = 0;

mClosed = true;
return true;
}
Expand Down
4 changes: 4 additions & 0 deletions src/providers/ogr/qgsogrprovider.cpp
Expand Up @@ -201,6 +201,7 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
, ogrDriver( 0 )
, valid( false )
, featuresCounted( -1 )
, mActiveIterator( 0 )
{
QgsCPLErrorHandler handler;

Expand Down Expand Up @@ -345,6 +346,9 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )

QgsOgrProvider::~QgsOgrProvider()
{
if ( mActiveIterator )
mActiveIterator->close();

if ( ogrLayer != ogrOrigLayer )
{
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );
Expand Down

0 comments on commit a6c5fd8

Please sign in to comment.