Skip to content

Commit

Permalink
[network] Implement a smart cache size
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Sep 1, 2024
1 parent 2215a8c commit 0544092
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 14 deletions.
10 changes: 5 additions & 5 deletions src/app/options/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
mCacheDirectory->setPlaceholderText( QStandardPaths::writableLocation( QStandardPaths::CacheLocation ) );
mCacheSize->setMinimum( 0 );
mCacheSize->setMaximum( std::numeric_limits<int>::max() );
mCacheSize->setSingleStep( 1024 );
qint64 cacheSize = mSettings->value( QStringLiteral( "cache/size" ), 256 * 1024 * 1024 ).toLongLong();
mCacheSize->setValue( static_cast<int>( cacheSize / 1024 ) );
mCacheSize->setClearValue( 50 * 1024 );
mCacheSize->setSingleStep( 50 );
qint64 cacheSize = mSettings->value( QStringLiteral( "cache/size2" ), 0 ).toLongLong();
mCacheSize->setValue( static_cast<int>( cacheSize / 1024 / 1024 ) );
mCacheSize->setClearValue( 0 );
connect( mBrowseCacheDirectory, &QAbstractButton::clicked, this, &QgsOptions::browseCacheDirectory );
connect( mClearCache, &QAbstractButton::clicked, this, &QgsOptions::clearCache );

Expand Down Expand Up @@ -1583,7 +1583,7 @@ void QgsOptions::saveOptions()
else
mSettings->remove( QStringLiteral( "cache/directory" ) );

mSettings->setValue( QStringLiteral( "cache/size" ), QVariant::fromValue( mCacheSize->value() * 1024LL ) );
mSettings->setValue( QStringLiteral( "cache/size2" ), QVariant::fromValue( mCacheSize->value() * 1024LL * 1024LL ) );

//url with no proxy at all
QStringList noProxyUrls;
Expand Down
7 changes: 6 additions & 1 deletion src/core/network/qgsnetworkaccessmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,8 +752,13 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache( Qt::ConnectionType conn
QString cacheDirectory = settings.value( QStringLiteral( "cache/directory" ) ).toString();
if ( cacheDirectory.isEmpty() )
cacheDirectory = QStandardPaths::writableLocation( QStandardPaths::CacheLocation );
const qint64 cacheSize = settings.value( QStringLiteral( "cache/size" ), 256 * 1024 * 1024 ).toLongLong();
newcache->setCacheDirectory( cacheDirectory );
qint64 cacheSize = settings.value( QStringLiteral( "cache/size2" ), 0 ).toLongLong();
if ( cacheSize == 0 )
{
// Calculatre maximum cache size based on available free space
cacheSize = QgsNetworkDiskCache::smartCacheSize( cacheDirectory );
}
newcache->setMaximumCacheSize( cacheSize );
QgsDebugMsgLevel( QStringLiteral( "cacheDirectory: %1" ).arg( newcache->cacheDirectory() ), 4 );
QgsDebugMsgLevel( QStringLiteral( "maximumCacheSize: %1" ).arg( newcache->maximumCacheSize() ), 4 );
Expand Down
73 changes: 73 additions & 0 deletions src/core/network/qgsnetworkdiskcache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

#include "qgsnetworkdiskcache.h"

#include <QStorageInfo>
#include <mutex>

///@cond PRIVATE
ExpirableNetworkDiskCache QgsNetworkDiskCache::sDiskCache;
///@endcond
Expand Down Expand Up @@ -111,3 +114,73 @@ void QgsNetworkDiskCache::clear()
const QMutexLocker lock( &sDiskCacheMutex );
return sDiskCache.clear();
}

qint64 QgsNetworkDiskCache::smartCacheSize( const QString &cacheDir )
{
static qint64 cacheSize = 0;
static std::once_flag initialized;
std::call_once( initialized, [ = ]
{
std::function<qint64( const QString & )> dirSize;
dirSize = [&dirSize]( const QString & dirPath ) -> qint64
{
qint64 size = 0;
QDir dir( dirPath );

const QStringList filePaths = dir.entryList( QDir::Files | QDir::System | QDir::Hidden );
for ( const QString &filePath : filePaths )
{
QFileInfo fi( dir, filePath );
size += fi.size();
}

const QStringList childDirPaths = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden );
for ( const QString &childDirPath : childDirPaths )
{
size += dirSize( dirPath + QDir::separator() + childDirPath );
}

return size;
};

qint64 bytesFree;
QStorageInfo storageInfo( cacheDir );
bytesFree = storageInfo.bytesFree() + dirSize( cacheDir );

// Logic taken from Firefox's smart cache size handling
int available10MB = bytesFree / 1024 / ( 1024 * 10 );
if ( available10MB > 2500 )
{
// Cap the cache size to 1GB
cacheSize = 100;
}
else
{
if ( available10MB > 700 )
{
// Add 2.5% of the free space above 7GB
cacheSize += static_cast<qint64>( ( available10MB - 700 ) * 0.025 );
available10MB = 700;
}
if ( available10MB > 50 )
{
// Add 7.5% of free sapce between 500MB to 7GB
cacheSize += static_cast<qint64>( ( available10MB - 50 ) * 0.075 );
available10MB = 50;
}

#if defined( Q_OS_ANDROID )
// On Android, smaller/older devices may have very little storage

// Add 16% of free space up to 500 MB
cacheSize += std::max( 2, static_cast<int>( available10MB * 0.16 ) );
#else
// Add 30% of free space up to 500 MB
cacheSize += std::max( 5, static_cast<int>( available10MB * 0.30 ) );
#endif
}
cacheSize = cacheSize * 10 * 1024 * 1024;
} );

return cacheSize;
}
10 changes: 9 additions & 1 deletion src/core/network/qgsnetworkdiskcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

#define SIP_NO_FILE

#include "qgis_core.h"

#include <QNetworkDiskCache>
#include <QMutex>

Expand All @@ -45,7 +47,7 @@ class ExpirableNetworkDiskCache : public QNetworkDiskCache
*
* \note not available in Python bindings
*/
class QgsNetworkDiskCache : public QNetworkDiskCache
class CORE_EXPORT QgsNetworkDiskCache : public QNetworkDiskCache
{
Q_OBJECT

Expand Down Expand Up @@ -87,6 +89,12 @@ class QgsNetworkDiskCache : public QNetworkDiskCache
//! \see QNetworkDiskCache::fileMetaData()
QNetworkCacheMetaData fileMetaData( const QString &fileName ) const;

/**
* Returns a smart cache size based on available megabytes.
* \since QGIS 3.40
*/
static qint64 smartCacheSize( const QString &path );

public slots:
//! \see QNetworkDiskCache::clear()
void clear() override;
Expand Down
9 changes: 7 additions & 2 deletions src/core/qgstiledownloadmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "qgslogger.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsnetworkdiskcache.h"
#include "qgsrangerequestcache.h"
#include "qgssettings.h"

Expand Down Expand Up @@ -198,9 +199,13 @@ QgsTileDownloadManager::QgsTileDownloadManager()
cacheDirectory.push_back( QDir::separator() );
}
cacheDirectory += QLatin1String( "http-ranges" );
const qint64 cacheSize = settings.value( QStringLiteral( "cache/size" ), 256 * 1024 * 1024 ).toLongLong();

mRangesCache->setCacheDirectory( cacheDirectory );
qint64 cacheSize = settings.value( QStringLiteral( "cache/size2" ), 0 ).toLongLong();
if ( cacheSize == 0 )
{
// Calculatre maximum cache size based on available free space
cacheSize = QgsNetworkDiskCache::smartCacheSize( cacheDirectory );
}
mRangesCache->setCacheSize( cacheSize );
}

Expand Down
8 changes: 7 additions & 1 deletion src/server/qgsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "qgslogger.h"
#include "qgsmapserviceexception.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsnetworkdiskcache.h"
#include "qgsserverlogger.h"
#include "qgsserverrequest.h"
#include "qgsfilterresponsedecorator.h"
Expand Down Expand Up @@ -88,9 +89,14 @@ void QgsServer::setupNetworkAccessManager()
const QSettings settings;
QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
const qint64 cacheSize = sSettings()->cacheSize();
const QString cacheDirectory = sSettings()->cacheDirectory();
cache->setCacheDirectory( cacheDirectory );
qint64 cacheSize = sSettings()->cacheSize();
if ( cacheSize == 0 )
{
// Calculatre maximum cache size based on available free space
cacheSize = QgsNetworkDiskCache::smartCacheSize( cacheDirectory );
}
cache->setMaximumCacheSize( cacheSize );
QgsMessageLog::logMessage( QStringLiteral( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
QgsMessageLog::logMessage( QStringLiteral( "maximumCacheSize: %1" ).arg( cache->maximumCacheSize() ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
Expand Down
4 changes: 2 additions & 2 deletions src/server/qgsserversettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ void QgsServerSettings::initSettings()
const Setting sCacheSize = { QgsServerSettingsEnv::QGIS_SERVER_CACHE_SIZE,
QgsServerSettingsEnv::DEFAULT_VALUE,
QStringLiteral( "Specify the cache size" ),
QStringLiteral( "/cache/size" ),
QStringLiteral( "/cache/size2" ),
QMetaType::Type::LongLong,
QVariant( 256 * 1024 * 1024 ),
0,
QVariant()
};
mSettings[ sCacheSize.envVar ] = sCacheSize;
Expand Down
26 changes: 24 additions & 2 deletions src/ui/qgsoptionsbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -4862,7 +4862,7 @@ The bigger the number, the faster zooming with the mouse wheel will be.</string>
<item row="4" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Size [KiB]</string>
<string>Size</string>
</property>
</widget>
</item>
Expand All @@ -4877,7 +4877,29 @@ The bigger the number, the faster zooming with the mouse wheel will be.</string>
<widget class="QLineEdit" name="mCacheDirectory"/>
</item>
<item row="4" column="1">
<widget class="QgsSpinBox" name="mCacheSize"/>
<widget class="QgsSpinBox" name="mCacheSize">
<property name="suffix">
<string> MB</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="clearValue">
<number>0</number>
</property>
<property name="showClearButton" stdset="0">
<bool>true</bool>
</property>
<property name="specialValueText">
<string>Smart cache size</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="mBrowseCacheDirectory">
Expand Down

0 comments on commit 0544092

Please sign in to comment.