Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Invalidate cache layers if project files are changed
  • Loading branch information
mhugent authored and jef-n committed May 17, 2012
1 parent 4be7726 commit f4c21a1
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/mapserver/qgshostedrdsbuilder.cpp
Expand Up @@ -67,7 +67,7 @@ QgsMapLayer* QgsHostedRDSBuilder::createMapLayer( const QDomElement& elem,
rl = new QgsRasterLayer( uri, layerNameFromUri( uri ) );
if ( allowCaching )
{
QgsMSLayerCache::instance()->insertLayer( uri, layerName, rl );
QgsMSLayerCache::instance()->insertLayer( uri, layerName, rl, "" /*todo: add project file path*/ );
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/mapserver/qgshostedvdsbuilder.cpp
Expand Up @@ -75,7 +75,7 @@ QgsMapLayer* QgsHostedVDSBuilder::createMapLayer( const QDomElement& elem,

if ( allowCaching )
{
QgsMSLayerCache::instance()->insertLayer( uri, layerName, ml );
QgsMSLayerCache::instance()->insertLayer( uri, layerName, ml, "" /*todo: add project file path*/ );
}
else
{
Expand Down
51 changes: 49 additions & 2 deletions src/mapserver/qgsmslayercache.cpp
Expand Up @@ -36,6 +36,7 @@ QgsMSLayerCache* QgsMSLayerCache::instance()

QgsMSLayerCache::QgsMSLayerCache()
{
QObject::connect( &mFileSystemWatcher, SIGNAL( fileChanged( const QString& ) ), this, SLOT( removeProjectFileLayers( const QString& ) ) );
}

QgsMSLayerCache::~QgsMSLayerCache()
Expand All @@ -48,7 +49,7 @@ QgsMSLayerCache::~QgsMSLayerCache()
delete mInstance;
}

void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QList<QString>& tempFiles )
void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QString& configFile, const QList<QString>& tempFiles )
{
QgsDebugMsg( "inserting layer" );
if ( mEntries.size() > std::max( DEFAULT_MAX_N_LAYERS, mProjectMaxLayers ) ) //force cache layer examination after 10 inserted layers
Expand All @@ -69,8 +70,21 @@ void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName,
newEntry.creationTime = time( NULL );
newEntry.lastUsedTime = time( NULL );
newEntry.temporaryFiles = tempFiles;
newEntry.configFile = configFile;

mEntries.insert( urlLayerPair, newEntry );

//update config file map
QHash< QString, int >::iterator configIt = mConfigFiles.find( configFile );
if ( configIt == mConfigFiles.end() )
{
mConfigFiles.insert( configFile, 1 );
mFileSystemWatcher.addPath( configFile );
}
else
{
mConfigFiles[configFile] = configIt.value() + 1; //increment reference counter
}
}

QgsMapLayer* QgsMSLayerCache::searchLayer( const QString& url, const QString& layerName )
Expand Down Expand Up @@ -98,6 +112,27 @@ QgsMapLayer* QgsMSLayerCache::searchLayer( const QString& url, const QString& la
}
}

void QgsMSLayerCache::removeProjectFileLayers( const QString& project )
{
QList< QPair< QString, QString > > removeEntries;

QHash<QPair<QString, QString>, QgsMSLayerCacheEntry>::iterator entryIt = mEntries.begin();
for ( ; entryIt != mEntries.end(); ++entryIt )
{
if ( entryIt.value().configFile == project )
{
removeEntries.push_back( entryIt.key() );
freeEntryRessources( entryIt.value() );
}
}

QList< QPair< QString, QString > >::const_iterator removeIt = removeEntries.constBegin();
for ( ; removeIt != removeEntries.constEnd(); ++removeIt )
{
mEntries.remove( *removeIt );
}
}

void QgsMSLayerCache::updateEntries()
{
QgsDebugMsg( "updateEntries" );
Expand Down Expand Up @@ -142,7 +177,7 @@ void QgsMSLayerCache::freeEntryRessources( QgsMSLayerCacheEntry& entry )
{
delete entry.layerPointer;

//todo: remove the temporary files of a layer
//remove the temporary files of a layer
foreach( QString file, entry.temporaryFiles )
{
//remove the temporary file
Expand All @@ -153,4 +188,16 @@ void QgsMSLayerCache::freeEntryRessources( QgsMSLayerCacheEntry& entry )
QgsDebugMsg( removeFile.errorString() );
}
}

//counter
int configFileCount = mConfigFiles[entry.configFile];
if ( configFileCount < 2 )
{
mConfigFiles.remove( entry.configFile );
mFileSystemWatcher.removePath( entry.configFile );
}
else
{
mConfigFiles[entry.configFile] = configFileCount - 1;
}
}
18 changes: 16 additions & 2 deletions src/mapserver/qgsmslayercache.h
Expand Up @@ -19,7 +19,9 @@
#define QGSMSLAYERCACHE_H

#include <time.h>
#include <QFileSystemWatcher>
#include <QHash>
#include <QObject>
#include <QPair>
#include <QString>

Expand All @@ -32,11 +34,12 @@ struct QgsMSLayerCacheEntry
QString url; //datasource url
QgsMapLayer* layerPointer;
QList<QString> temporaryFiles; //path to the temporary files written for the layer
QString configFile; //path to the project file associated with the layer
};

/**A singleton class that caches layer objects for the
QGIS mapserver*/
class QgsMSLayerCache
class QgsMSLayerCache: public QObject
{
public:
static QgsMSLayerCache* instance();
Expand All @@ -46,7 +49,7 @@ class QgsMSLayerCache
@param url the layer datasource
@param layerName the layer name (to distinguish between different layers in a request using the same datasource
@param tempFiles some layers have temporary files. The cash makes sure they are removed when removing the layer from the cash*/
void insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QList<QString>& tempFiles = QList<QString>() );
void insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QString& configFile, const QList<QString>& tempFiles = QList<QString>() );
/**Searches for the layer with the given url.
@return a pointer to the layer or 0 if no such layer*/
QgsMapLayer* searchLayer( const QString& url, const QString& layerName );
Expand Down Expand Up @@ -75,8 +78,19 @@ class QgsMSLayerCache
layer names*/
QHash<QPair<QString, QString>, QgsMSLayerCacheEntry> mEntries;

/**Config files used in the cache (with reference counter)*/
QHash< QString, int > mConfigFiles;

/**Check for configuration file updates (remove layers from cache if configuration file changes)*/
QFileSystemWatcher mFileSystemWatcher;

/**Maximum number of layers in the cache, overrides DEFAULT_MAX_N_LAYERS if larger*/
int mProjectMaxLayers;

private slots:

/**Removes entries from a project (e.g. if a project file has changed)*/
void removeProjectFileLayers( const QString& project );
};

#endif
2 changes: 1 addition & 1 deletion src/mapserver/qgsprojectparser.cpp
Expand Up @@ -1005,7 +1005,7 @@ QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem,
layer->setLayerName( layerName( elem ) );
if ( useCache )
{
QgsMSLayerCache::instance()->insertLayer( absoluteUri, id, layer );
QgsMSLayerCache::instance()->insertLayer( absoluteUri, id, layer, mProjectPath );
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions src/mapserver/qgsremoteowsbuilder.cpp
Expand Up @@ -115,7 +115,7 @@ QgsMapLayer* QgsRemoteOWSBuilder::createMapLayer(
{
if ( allowCaching )
{
QgsMSLayerCache::instance()->insertLayer( url, layerName, result );
QgsMSLayerCache::instance()->insertLayer( url, layerName, result, "" /*todo: add project file path*/ );
}
else
{
Expand Down Expand Up @@ -215,7 +215,7 @@ QgsRasterLayer* QgsRemoteOWSBuilder::wmsLayerFromUrl( const QString& url, const
//insert into cache
if ( allowCaching )
{
QgsMSLayerCache::instance()->insertLayer( url, layerName, result );
QgsMSLayerCache::instance()->insertLayer( url, layerName, result, "" /*todo: add project file path*/ );
}
else
{
Expand Down Expand Up @@ -414,7 +414,7 @@ QgsVectorLayer* QgsRemoteOWSBuilder::sosLayer( const QDomElement& remoteOWSElem,
{
if ( allowCaching )
{
QgsMSLayerCache::instance()->insertLayer( providerUrl, layerName, sosLayer );
QgsMSLayerCache::instance()->insertLayer( providerUrl, layerName, sosLayer, "" /*todo: add project file path*/ );
}
else
{
Expand Down

0 comments on commit f4c21a1

Please sign in to comment.