18#ifndef QGSABSTRACTCONTENTCACHE_H
19#define QGSABSTRACTCONTENTCACHE_H
31#include <QRecursiveMutex>
37#include <QNetworkReply>
79 int mFileModifiedCheckTimeout = 30000;
95 return other.
path == path;
158 virtual bool checkReply( QNetworkReply *reply,
const QString &path )
const
158 virtual bool checkReply( QNetworkReply *reply,
const QString &path )
const {
…}
173 virtual void onRemoteContentFetched(
const QString &url,
bool success );
210 const QString &typeString = QString(),
211 long maxCacheSize = 20000000,
212 int fileModifiedCheckTimeout = 30000 )
214 , mMaxCacheSize( maxCacheSize )
215 , mFileModifiedCheckTimeout( fileModifiedCheckTimeout )
216 , mTypeString( typeString.isEmpty() ? QObject::tr(
"Content" ) : typeString )
222 qDeleteAll( mEntryLookup );
233 if ( mLeastRecentEntry == mMostRecentEntry )
237 T *entry = mLeastRecentEntry;
238 while ( entry && ( mTotalSize > mMaxCacheSize ) )
241 entry =
static_cast< T *
>( entry->nextEntry );
243 takeEntryFromList( bkEntry );
244 mEntryLookup.remove( bkEntry->path, bkEntry );
245 mTotalSize -= bkEntry->dataSize();
263 QByteArray getContent(
const QString &path,
const QByteArray &missingContent,
const QByteArray &fetchingContent,
bool blocking =
false )
const;
267 const QMutexLocker locker( &mMutex );
268 mPendingRemoteUrls.remove( url );
270 T *nextEntry = mLeastRecentEntry;
271 while ( T *entry = nextEntry )
273 nextEntry =
static_cast< T *
>( entry->nextEntry );
274 if ( entry->path == url )
276 takeEntryFromList( entry );
277 mEntryLookup.remove( entry->path, entry );
278 mTotalSize -= entry->dataSize();
284 emit remoteContentFetched( url );
328 const QString path = entryTemplate->path;
329 T *currentEntry =
nullptr;
330 const QList<T *> entries = mEntryLookup.values( path );
332 for ( T *cacheEntry : entries )
334 if ( cacheEntry->isEqual( entryTemplate ) )
336 if ( mFileModifiedCheckTimeout <= 0 || cacheEntry->fileModifiedLastCheckTimer.hasExpired( mFileModifiedCheckTimeout ) )
338 if ( !modified.isValid() )
339 modified = QFileInfo( path ).lastModified();
341 if ( cacheEntry->fileModified != modified )
344 cacheEntry->fileModifiedLastCheckTimer.restart();
346 currentEntry = cacheEntry;
354 currentEntry = insertCacheEntry( entryTemplate );
358 delete entryTemplate;
359 entryTemplate =
nullptr;
360 ( void )entryTemplate;
361 takeEntryFromList( currentEntry );
362 if ( !mMostRecentEntry )
364 mMostRecentEntry = currentEntry;
365 mLeastRecentEntry = currentEntry;
369 mMostRecentEntry->nextEntry = currentEntry;
370 currentEntry->previousEntry = mMostRecentEntry;
371 currentEntry->nextEntry =
nullptr;
372 mMostRecentEntry = currentEntry;
387 long mMaxCacheSize = 20000000;
396 T *insertCacheEntry( T *entry )
398 entry->mFileModifiedCheckTimeout = mFileModifiedCheckTimeout;
400 if ( !entry->path.startsWith( QLatin1String(
"base64:" ) ) )
402 entry->fileModified = QFileInfo( entry->path ).lastModified();
403 entry->fileModifiedLastCheckTimer.start();
406 mEntryLookup.insert( entry->path, entry );
409 if ( !mMostRecentEntry )
411 mLeastRecentEntry = entry;
412 mMostRecentEntry = entry;
413 entry->previousEntry =
nullptr;
414 entry->nextEntry =
nullptr;
418 entry->previousEntry = mMostRecentEntry;
419 entry->nextEntry =
nullptr;
420 mMostRecentEntry->nextEntry = entry;
421 mMostRecentEntry = entry;
432 void takeEntryFromList( T *entry )
439 if ( entry->previousEntry )
441 entry->previousEntry->nextEntry = entry->nextEntry;
445 mLeastRecentEntry =
static_cast< T *
>( entry->nextEntry );
447 if ( entry->nextEntry )
449 entry->nextEntry->previousEntry = entry->previousEntry;
453 mMostRecentEntry =
static_cast< T *
>( entry->previousEntry );
460 void printEntryList()
462 QgsDebugMsgLevel( QStringLiteral(
"****************cache entry list*************************" ), 1 );
464 T *entry = mLeastRecentEntry;
469 entry =
static_cast< T *
>( entry->nextEntry );
474 QMultiHash< QString, T * > mEntryLookup;
477 int mFileModifiedCheckTimeout = 30000;
481 T *mLeastRecentEntry =
nullptr;
482 T *mMostRecentEntry =
nullptr;
484 mutable QCache< QString, QByteArray > mRemoteContentCache;
485 mutable QSet< QString > mPendingRemoteUrls;
489 friend class TestQgsSvgCache;
490 friend class TestQgsImageCache;
A QObject derived base class for QgsAbstractContentCache.
void remoteContentFetched(const QString &url)
Emitted when the cache has finished retrieving content from a remote url.
virtual bool checkReply(QNetworkReply *reply, const QString &path) const
Runs additional checks on a network reply to ensure that the reply content is consistent with that re...
Base class for entries in a QgsAbstractContentCache.
virtual int dataSize() const =0
Returns the memory usage in bytes for the entry.
virtual void dump() const =0
Dumps debugging strings containing the item's properties.
virtual ~QgsAbstractContentCacheEntry()=default
QElapsedTimer fileModifiedLastCheckTimer
Time since last check of file modified date.
QgsAbstractContentCacheEntry(const QgsAbstractContentCacheEntry &rh)=delete
QgsAbstractContentCacheEntry cannot be copied.
QgsAbstractContentCacheEntry & operator=(const QgsAbstractContentCacheEntry &rh)=delete
QgsAbstractContentCacheEntry cannot be copied.
QString path
Represents the absolute path to a file, a remote URL, or a base64 encoded string.
virtual bool isEqual(const QgsAbstractContentCacheEntry *other) const =0
Tests whether this entry matches another entry.
QDateTime fileModified
Timestamp when file was last modified.
bool operator==(const QgsAbstractContentCacheEntry &other) const
Abstract base class for file content caches, such as SVG or raster image caches.
T * findExistingEntry(T *entryTemplate)
Returns the existing entry from the cache which matches entryTemplate (deleting entryTemplate when do...
~QgsAbstractContentCache() override
void onRemoteContentFetched(const QString &url, bool success) override
Triggered after remote content (i.e.
QgsAbstractContentCache(QObject *parent=nullptr, const QString &typeString=QString(), long maxCacheSize=20000000, int fileModifiedCheckTimeout=30000)
Constructor for QgsAbstractContentCache, with the specified parent object.
void trimToMaximumSize()
Removes the least used cache entries until the maximum cache size is under the predefined size limit.
bool waitForTaskFinished(QgsNetworkContentFetcherTask *task) const
Blocks the current thread until the task finishes (or user's preset network timeout expires)
static int timeout()
Returns the network timeout length, in milliseconds.
Handles HTTP network content fetching in a background task.
void fetched()
Emitted when the network content has been fetched, regardless of whether the fetch was successful or ...
TaskStatus status() const
Returns the current task status.
@ Complete
Task successfully completed.
bool waitForFinished(int timeout=30000)
Blocks the current thread until the task finishes or a maximum of timeout milliseconds.
#define QgsDebugMsgLevel(str, level)