Skip to content

Commit a6c5fd8

Browse files
committedJan 16, 2013
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.
1 parent de3f07e commit a6c5fd8

23 files changed

+136
-12
lines changed
 

‎src/core/qgsvectorlayer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
10841084
//annotation form for this layer
10851085
QString mAnnotationForm;
10861086

1087-
QgsFeatureIterator mLayerIterator; // temporary
1087+
QgsFeatureIterator mLayerIterator; // temporary: to support old API
10881088
friend class QgsVectorLayerFeatureIterator;
10891089
#if 0
10901090
bool mFetching;

‎src/core/qgsvectorlayerfeatureiterator.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ bool QgsVectorLayerFeatureIterator::nextFeature( QgsFeature& f )
108108
return true;
109109
}
110110

111+
close();
111112
return false;
112113
}
113114

‎src/providers/delimitedtext/qgsdelimitedtextfeatureiterator.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
QgsDelimitedTextFeatureIterator::QgsDelimitedTextFeatureIterator( QgsDelimitedTextProvider* p, const QgsFeatureRequest& request )
1010
: QgsAbstractFeatureIterator( request ), P( p )
1111
{
12+
// make sure that only one iterator is active
13+
if ( P->mActiveIterator )
14+
P->mActiveIterator->close();
15+
P->mActiveIterator = this;
16+
1217
rewind();
1318
}
1419

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

101+
close();
96102
return false;
97103
}
98104

@@ -117,6 +123,9 @@ bool QgsDelimitedTextFeatureIterator::close()
117123
if ( mClosed )
118124
return false;
119125

126+
// tell provider that this iterator is not active anymore
127+
P->mActiveIterator = 0;
128+
120129
mClosed = true;
121130
return true;
122131
}

‎src/providers/delimitedtext/qgsdelimitedtextprovider.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
148148
, mShowInvalidLines( false )
149149
, mCrs()
150150
, mWkbType( QGis::WKBUnknown )
151+
, mActiveIterator( 0 )
151152
{
152153
QUrl url = QUrl::fromEncoded( uri.toAscii() );
153154

@@ -449,6 +450,9 @@ QgsDelimitedTextProvider::QgsDelimitedTextProvider( QString uri )
449450

450451
QgsDelimitedTextProvider::~QgsDelimitedTextProvider()
451452
{
453+
if ( mActiveIterator )
454+
mActiveIterator->close();
455+
452456
if ( mFile )
453457
mFile->close();
454458
delete mFile;

‎src/providers/delimitedtext/qgsdelimitedtextprovider.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,5 @@ class QgsDelimitedTextProvider : public QgsVectorDataProvider
219219
QStringList splitLine( QString line ) { return splitLine( line, mDelimiterType, mDelimiter ); }
220220

221221
friend class QgsDelimitedTextFeatureIterator;
222+
QgsDelimitedTextFeatureIterator* mActiveIterator;
222223
};

‎src/providers/gpx/qgsgpxfeatureiterator.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
QgsGPXFeatureIterator::QgsGPXFeatureIterator( QgsGPXProvider* p, const QgsFeatureRequest& request )
1414
: QgsAbstractFeatureIterator( request ), P( p )
1515
{
16+
// make sure that only one iterator is active
17+
if ( P->mActiveIterator )
18+
P->mActiveIterator->close();
19+
P->mActiveIterator = this;
20+
1621
rewind();
1722
}
1823

@@ -50,6 +55,9 @@ bool QgsGPXFeatureIterator::close()
5055

5156
// nothing to do
5257

58+
// tell provider that this iterator is not active anymore
59+
P->mActiveIterator = 0;
60+
5361
mClosed = true;
5462
return true;
5563
}
@@ -67,7 +75,9 @@ bool QgsGPXFeatureIterator::nextFeature( QgsFeature& feature )
6775

6876
if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
6977
{
70-
return readFid( feature );
78+
bool res = readFid( feature );
79+
close();
80+
return res;
7181
}
7282

7383

@@ -111,6 +121,7 @@ bool QgsGPXFeatureIterator::nextFeature( QgsFeature& feature )
111121
}
112122
}
113123

124+
close();
114125
return false;
115126
}
116127

‎src/providers/gpx/qgsgpxprovider.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const QString GPX_DESCRIPTION = QObject::tr( "GPS eXchange format provider" );
6666

6767
QgsGPXProvider::QgsGPXProvider( QString uri ) :
6868
QgsVectorDataProvider( uri )
69+
, mActiveIterator( 0 )
6970
{
7071
// assume that it won't work
7172
mValid = false;
@@ -110,6 +111,9 @@ QgsGPXProvider::QgsGPXProvider( QString uri ) :
110111

111112
QgsGPXProvider::~QgsGPXProvider()
112113
{
114+
if ( mActiveIterator )
115+
mActiveIterator->close();
116+
113117
QgsGPSData::releaseData( mFileName );
114118
}
115119

‎src/providers/gpx/qgsgpxprovider.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class QFile;
2828
class QDomDocument;
2929
class QgsGPSData;
3030

31+
class QgsGPXFeatureIterator;
3132

3233
/**
3334
\class QgsGPXProvider
@@ -171,4 +172,5 @@ class QgsGPXProvider : public QgsVectorDataProvider
171172
wkbPoint mWKBpt;
172173

173174
friend class QgsGPXFeatureIterator;
175+
QgsGPXFeatureIterator* mActiveIterator;
174176
};

‎src/providers/grass/qgsgrassfeatureiterator.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ extern "C"
2121
QgsGrassFeatureIterator::QgsGrassFeatureIterator( QgsGrassProvider* p, const QgsFeatureRequest& request )
2222
: QgsAbstractFeatureIterator( request ), P( p )
2323
{
24+
// make sure that only one iterator is active
25+
if ( P->mActiveIterator )
26+
P->mActiveIterator->close();
27+
P->mActiveIterator = this;
28+
2429
// check if outdated and update if necessary
2530
P->ensureUpdated();
2631

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

129134
if ( P->isEdited() || P->isFrozen() || !P->mValid )
135+
{
136+
close();
130137
return false;
138+
}
131139

132140
if ( P->mCidxFieldIndex < 0 || mNextCidx >= P->mCidxFieldNumCats )
141+
{
142+
close();
133143
return false; // No features, no features in this layer
144+
}
134145

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

@@ -154,7 +165,10 @@ bool QgsGrassFeatureIterator::nextFeature( QgsFeature& feature )
154165
break;
155166
}
156167
if ( !found )
168+
{
169+
close();
157170
return false; // No more features
171+
}
158172
#if QGISDEBUG > 3
159173
QgsDebugMsg( QString( "cat = %1 type = %2 id = %3" ).arg( cat ).arg( type ).arg( id ) );
160174
#endif
@@ -209,6 +223,9 @@ bool QgsGrassFeatureIterator::close()
209223

210224
free( mSelection );
211225

226+
// tell provider that this iterator is not active anymore
227+
P->mActiveIterator = 0;
228+
212229
mClosed = true;
213230
return true;
214231
}

‎src/providers/grass/qgsgrassprovider.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ static QString GRASS_DESCRIPTION = "Grass provider"; // XXX verify this
7373

7474
QgsGrassProvider::QgsGrassProvider( QString uri )
7575
: QgsVectorDataProvider( uri )
76+
, mActiveIterator( 0 )
7677
{
7778
QgsDebugMsg( QString( "QgsGrassProvider URI: %1" ).arg( uri ) );
7879

@@ -256,6 +257,10 @@ void QgsGrassProvider::update( void )
256257
QgsGrassProvider::~QgsGrassProvider()
257258
{
258259
QgsDebugMsg( "entered." );
260+
261+
if ( mActiveIterator )
262+
mActiveIterator->close();
263+
259264
closeLayer( mLayerId );
260265
}
261266

‎src/providers/grass/qgsgrassprovider.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
class QgsFeature;
2020
class QgsField;
21+
22+
class QgsGrassFeatureIterator;
23+
2124
#include <QDateTime>
2225

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

640643
friend class QgsGrassFeatureIterator;
644+
QgsGrassFeatureIterator* mActiveIterator;
641645
};
642646

643647
#endif // QGSGRASSPROVIDER_H

‎src/providers/memory/qgsmemoryfeatureiterator.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryProvider* p, const QgsFeatureRequest& request )
1010
: QgsAbstractFeatureIterator( request ), P( p ), mSelectRectGeom( NULL )
1111
{
12+
// make sure that only one iterator is active
13+
if ( P->mActiveIterator )
14+
P->mActiveIterator->close();
15+
P->mActiveIterator = this;
16+
1217
if ( mRequest.filterType() == QgsFeatureRequest::FilterRect && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
1318
{
1419
mSelectRectGeom = QgsGeometry::fromRect( request.filterRect() );
@@ -85,6 +90,9 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature& feature )
8590
feature = P->mFeatures[*mFeatureIdListIterator];
8691
mFeatureIdListIterator++;
8792
}
93+
else
94+
close();
95+
8896
return hasFeature;
8997
}
9098

@@ -131,6 +139,8 @@ bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( QgsFeature& feature )
131139
feature.setValid( true );
132140
feature.setFields( &P->mFields ); // allow name-based attribute lookups
133141
}
142+
else
143+
close();
134144

135145
return hasFeature;
136146
}
@@ -156,6 +166,9 @@ bool QgsMemoryFeatureIterator::close()
156166
delete mSelectRectGeom;
157167
mSelectRectGeom = NULL;
158168

169+
// tell provider that this iterator is not active anymore
170+
P->mActiveIterator = 0;
171+
159172
mClosed = true;
160173
return true;
161174
}

‎src/providers/memory/qgsmemoryprovider.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ static const QString TEXT_PROVIDER_KEY = "memory";
3131
static const QString TEXT_PROVIDER_DESCRIPTION = "Memory provider";
3232

3333
QgsMemoryProvider::QgsMemoryProvider( QString uri )
34-
: QgsVectorDataProvider( uri ),
35-
mSpatialIndex( NULL )
34+
: QgsVectorDataProvider( uri )
35+
, mSpatialIndex( NULL )
36+
, mActiveIterator( 0 )
3637
{
3738
// Initialize the geometry with the uri to support old style uri's
3839
// (ie, just 'point', 'line', 'polygon')
@@ -138,6 +139,9 @@ QgsMemoryProvider::QgsMemoryProvider( QString uri )
138139

139140
QgsMemoryProvider::~QgsMemoryProvider()
140141
{
142+
if ( mActiveIterator )
143+
mActiveIterator->close();
144+
141145
delete mSpatialIndex;
142146
}
143147

‎src/providers/memory/qgsmemoryprovider.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ typedef QMap<QgsFeatureId, QgsFeature> QgsFeatureMap;
2121

2222
class QgsSpatialIndex;
2323

24+
class QgsMemoryFeatureIterator;
25+
2426
class QgsMemoryProvider : public QgsVectorDataProvider
2527
{
2628
Q_OBJECT
@@ -167,4 +169,5 @@ class QgsMemoryProvider : public QgsVectorDataProvider
167169
QgsSpatialIndex* mSpatialIndex;
168170

169171
friend class QgsMemoryFeatureIterator;
172+
QgsMemoryFeatureIterator* mActiveIterator;
170173
};

‎src/providers/ogr/qgsogrfeatureiterator.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrProvider* p, const QgsFeatureRequest& request )
2020
: QgsAbstractFeatureIterator( request ), P( p )
2121
{
22+
// make sure that only one iterator is active
23+
if ( P->mActiveIterator )
24+
P->mActiveIterator->close();
25+
P->mActiveIterator = this;
26+
2227
// set the selection rectangle pointer to 0
2328
mSelectionRectangle = 0;
2429

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

8691
if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )
8792
{
88-
// make sure that only one next feature call returns a valid feature!
89-
if ( mFeatureFetched )
90-
return false;
91-
9293
OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) );
9394
if ( !fet )
95+
{
96+
close();
9497
return false;
98+
}
9599

96100
// skip features without geometry
97101
if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom )
98102
{
99103
OGR_F_Destroy( fet );
104+
close();
100105
return false;
101106
}
102107

103108
readFeature( fet, feature );
104109
feature.setValid( true );
105-
mFeatureFetched = true;
110+
close(); // the feature has been read: we have finished here
106111
return true;
107112
}
108113

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

149154
QgsDebugMsg( "Feature is null" );
150155

151-
// probably should reset reading here
152-
rewind();
153-
156+
close();
154157
return false;
155158
}
156159

@@ -177,6 +180,9 @@ bool QgsOgrFeatureIterator::close()
177180
mSelectionRectangle = 0;
178181
}
179182

183+
// tell provider that this iterator is not active anymore
184+
P->mActiveIterator = 0;
185+
180186
mClosed = true;
181187
return true;
182188
}

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ QgsOgrProvider::QgsOgrProvider( QString const & uri )
201201
, ogrDriver( 0 )
202202
, valid( false )
203203
, featuresCounted( -1 )
204+
, mActiveIterator( 0 )
204205
{
205206
QgsCPLErrorHandler handler;
206207

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

346347
QgsOgrProvider::~QgsOgrProvider()
347348
{
349+
if ( mActiveIterator )
350+
mActiveIterator->close();
351+
348352
if ( ogrLayer != ogrOrigLayer )
349353
{
350354
OGR_DS_ReleaseResultSet( ogrDataSource, ogrLayer );

0 commit comments

Comments
 (0)
Please sign in to comment.