QGIS API Documentation 3.39.0-Master (d85f3c2a281)
Loading...
Searching...
No Matches
qgsnetworkdiskcache.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsnetworkdiskcache.cpp - Thread-safe interface for QNetworkDiskCache
3 -------------------
4 begin : 2016-03-05
5 copyright : (C) 2016 by Juergen E. Fischer
6 email : jef at norbit dot de
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18
19#include "qgsnetworkdiskcache.h"
20
21#include <QStorageInfo>
22#include <mutex>
23
25ExpirableNetworkDiskCache QgsNetworkDiskCache::sDiskCache;
27QMutex QgsNetworkDiskCache::sDiskCacheMutex;
28
29QgsNetworkDiskCache::QgsNetworkDiskCache( QObject *parent )
30 : QNetworkDiskCache( parent )
31{
32}
33
35{
36 const QMutexLocker lock( &sDiskCacheMutex );
37 return sDiskCache.cacheDirectory();
38}
39
40void QgsNetworkDiskCache::setCacheDirectory( const QString &cacheDir )
41{
42 const QMutexLocker lock( &sDiskCacheMutex );
43 sDiskCache.setCacheDirectory( cacheDir );
44}
45
47{
48 const QMutexLocker lock( &sDiskCacheMutex );
49 return sDiskCache.maximumCacheSize();
50}
51
53{
54 const QMutexLocker lock( &sDiskCacheMutex );
55
56 if ( size == 0 )
57 {
58 // Calculate maximum cache size based on available free space
59 size = smartCacheSize( sDiskCache.cacheDirectory() );
60 }
61
62 sDiskCache.setMaximumCacheSize( size );
63}
64
66{
67 const QMutexLocker lock( &sDiskCacheMutex );
68 return sDiskCache.cacheSize();
69}
70
71QNetworkCacheMetaData QgsNetworkDiskCache::metaData( const QUrl &url )
72{
73 const QMutexLocker lock( &sDiskCacheMutex );
74 return sDiskCache.metaData( url );
75}
76
77void QgsNetworkDiskCache::updateMetaData( const QNetworkCacheMetaData &metaData )
78{
79 const QMutexLocker lock( &sDiskCacheMutex );
80 sDiskCache.updateMetaData( metaData );
81}
82
83QIODevice *QgsNetworkDiskCache::data( const QUrl &url )
84{
85 const QMutexLocker lock( &sDiskCacheMutex );
86 return sDiskCache.data( url );
87}
88
89bool QgsNetworkDiskCache::remove( const QUrl &url )
90{
91 const QMutexLocker lock( &sDiskCacheMutex );
92 return sDiskCache.remove( url );
93}
94
95QIODevice *QgsNetworkDiskCache::prepare( const QNetworkCacheMetaData &metaData )
96{
97 const QMutexLocker lock( &sDiskCacheMutex );
98 return sDiskCache.prepare( metaData );
99}
100
101void QgsNetworkDiskCache::insert( QIODevice *device )
102{
103 const QMutexLocker lock( &sDiskCacheMutex );
104 sDiskCache.insert( device );
105}
106
107QNetworkCacheMetaData QgsNetworkDiskCache::fileMetaData( const QString &fileName ) const
108{
109 const QMutexLocker lock( &sDiskCacheMutex );
110 return sDiskCache.fileMetaData( fileName );
111}
112
114{
115 const QMutexLocker lock( &sDiskCacheMutex );
116 return sDiskCache.runExpire();
117}
118
120{
121 const QMutexLocker lock( &sDiskCacheMutex );
122 return sDiskCache.clear();
123}
124
125qint64 QgsNetworkDiskCache::smartCacheSize( const QString &cacheDir )
126{
127 static qint64 cacheSize = 0;
128 static std::once_flag initialized;
129 std::call_once( initialized, [ = ]
130 {
131 std::function<qint64( const QString & )> dirSize;
132 dirSize = [&dirSize]( const QString & dirPath ) -> qint64
133 {
134 qint64 size = 0;
135 QDir dir( dirPath );
136
137 const QStringList filePaths = dir.entryList( QDir::Files | QDir::System | QDir::Hidden );
138 for ( const QString &filePath : filePaths )
139 {
140 QFileInfo fi( dir, filePath );
141 size += fi.size();
142 }
143
144 const QStringList childDirPaths = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::NoSymLinks );
145 for ( const QString &childDirPath : childDirPaths )
146 {
147 size += dirSize( dirPath + QDir::separator() + childDirPath );
148 }
149
150 return size;
151 };
152
153 qint64 bytesFree;
154 QStorageInfo storageInfo( cacheDir );
155 bytesFree = storageInfo.bytesFree() + dirSize( cacheDir );
156
157 // NOLINTBEGIN(bugprone-narrowing-conversions)
158 // Logic taken from Firefox's smart cache size handling
159 qint64 available10MB = bytesFree / 1024 / ( 1024LL * 10 );
160 qint64 cacheSize10MB = 0;
161 if ( available10MB > 2500 )
162 {
163 // Cap the cache size to 1GB
164 cacheSize10MB = 100;
165 }
166 else
167 {
168 if ( available10MB > 700 )
169 {
170 // Add 2.5% of the free space above 7GB
171 cacheSize10MB += ( available10MB - 700 ) * 0.025;
172 available10MB = 700;
173 }
174 if ( available10MB > 50 )
175 {
176 // Add 7.5% of free space between 500MB to 7GB
177 cacheSize10MB += ( available10MB - 50 ) * 0.075;
178 available10MB = 50;
179 }
180
181#if defined( Q_OS_ANDROID )
182 // On Android, smaller/older devices may have very little storage
183
184 // Add 16% of free space up to 500 MB
185 cacheSize10MB += std::max( 2LL, static_cast<qint64>( available10MB * 0.16 ) );
186#else
187 // Add 30% of free space up to 500 MB
188 cacheSize10MB += std::max( 5LL, static_cast<qint64>( available10MB * 0.30 ) );
189#endif
190 }
191 cacheSize = cacheSize10MB * 10 * 1024 * 1024;
192 // NOLINTEND(bugprone-narrowing-conversions)
193 } );
194
195 return cacheSize;
196}
void setCacheDirectory(const QString &cacheDir)
QIODevice * data(const QUrl &url) override
void updateMetaData(const QNetworkCacheMetaData &metaData) override
QNetworkCacheMetaData metaData(const QUrl &url) override
qint64 maximumCacheSize() const
QNetworkCacheMetaData fileMetaData(const QString &fileName) const
void insert(QIODevice *device) override
QIODevice * prepare(const QNetworkCacheMetaData &metaData) override
bool remove(const QUrl &url) override
void setMaximumCacheSize(qint64 size)
qint64 cacheSize() const override
QString cacheDirectory() const
static qint64 smartCacheSize(const QString &path)
Returns a smart cache size, in bytes, based on available free space.