diff options
author | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2019-06-14 15:11:32 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2019-06-18 16:26:51 +0300 |
commit | 68e3cbacbc35ae6cd6c1e0fe2ab59ed262c32786 (patch) | |
tree | a8eb342508e1b089d05eb4c35bb1ce424ecee088 /platform | |
parent | 78eeffe1717a37a91e6c59681421a20c52a4d003 (diff) | |
download | qtlocation-mapboxgl-68e3cbacbc35ae6cd6c1e0fe2ab59ed262c32786.tar.gz |
[core] Add method for setting a maximum size for the ambient cache
- Removed this parameter from the constructor, now that we
have a method to set it.
- Add the method and enforce the limits if the ambient cache exceeds the
size.
Diffstat (limited to 'platform')
3 files changed, 67 insertions, 17 deletions
diff --git a/platform/default/include/mbgl/storage/offline_database.hpp b/platform/default/include/mbgl/storage/offline_database.hpp index 59f41a723f..afce87b542 100644 --- a/platform/default/include/mbgl/storage/offline_database.hpp +++ b/platform/default/include/mbgl/storage/offline_database.hpp @@ -40,7 +40,7 @@ class OfflineDatabase : private util::noncopyable { public: // Limits affect ambient caching (put) only; resources required by offline // regions are exempt. - OfflineDatabase(std::string path, uint64_t maximumCacheSize = util::DEFAULT_MAX_CACHE_SIZE); + OfflineDatabase(std::string path); ~OfflineDatabase(); void changePath(const std::string&); @@ -86,6 +86,7 @@ public: expected<OfflineRegionDefinition, std::exception_ptr> getRegionDefinition(int64_t regionID); expected<OfflineRegionStatus, std::exception_ptr> getRegionCompletedStatus(int64_t regionID); + std::exception_ptr setMaximumAmbientCacheSize(uint64_t); void setOfflineMapboxTileCountLimit(uint64_t); uint64_t getOfflineMapboxTileCountLimit(); bool offlineMapboxTileCountLimitExceeded(); @@ -104,6 +105,7 @@ private: void migrateToVersion3(); void migrateToVersion6(); void cleanup(); + bool disabled(); mapbox::sqlite::Statement& getStatement(const char *); @@ -136,9 +138,9 @@ private: template <class T> T getPragma(const char *); - uint64_t maximumCacheSize; - + uint64_t maximumAmbientCacheSize = util::DEFAULT_MAX_CACHE_SIZE; uint64_t offlineMapboxTileCountLimit = util::mapbox::DEFAULT_OFFLINE_TILE_COUNT_LIMIT; + optional<uint64_t> offlineMapboxTileCount; bool evict(uint64_t neededFreeSize); diff --git a/platform/default/src/mbgl/storage/default_file_source.cpp b/platform/default/src/mbgl/storage/default_file_source.cpp index b296e448af..19932d8d00 100644 --- a/platform/default/src/mbgl/storage/default_file_source.cpp +++ b/platform/default/src/mbgl/storage/default_file_source.cpp @@ -20,10 +20,10 @@ namespace mbgl { class DefaultFileSource::Impl { public: - Impl(std::shared_ptr<FileSource> assetFileSource_, std::string cachePath, uint64_t maximumCacheSize) + Impl(std::shared_ptr<FileSource> assetFileSource_, std::string cachePath) : assetFileSource(std::move(assetFileSource_)) , localFileSource(std::make_unique<LocalFileSource>()) - , offlineDatabase(std::make_unique<OfflineDatabase>(cachePath, maximumCacheSize)) { + , offlineDatabase(std::make_unique<OfflineDatabase>(std::move(cachePath))) { } void setAPIBaseURL(const std::string& url) { @@ -196,6 +196,10 @@ public: callback(offlineDatabase->clearAmbientCache()); } + void setMaximumAmbientCacheSize(uint64_t size, std::function<void (std::exception_ptr)> callback) { + callback(offlineDatabase->setMaximumAmbientCacheSize(size)); + } + private: expected<OfflineDownload*, std::exception_ptr> getDownload(int64_t regionID) { auto it = downloads.find(regionID); @@ -220,17 +224,13 @@ private: std::unordered_map<int64_t, std::unique_ptr<OfflineDownload>> downloads; }; -DefaultFileSource::DefaultFileSource(const std::string& cachePath, - const std::string& assetPath, - uint64_t maximumCacheSize) - : DefaultFileSource(cachePath, std::make_unique<AssetFileSource>(assetPath), maximumCacheSize) { +DefaultFileSource::DefaultFileSource(const std::string& cachePath, const std::string& assetPath) + : DefaultFileSource(cachePath, std::make_unique<AssetFileSource>(assetPath)) { } -DefaultFileSource::DefaultFileSource(const std::string& cachePath, - std::unique_ptr<FileSource>&& assetFileSource_, - uint64_t maximumCacheSize) +DefaultFileSource::DefaultFileSource(const std::string& cachePath, std::unique_ptr<FileSource>&& assetFileSource_) : assetFileSource(std::move(assetFileSource_)) - , impl(std::make_unique<util::Thread<Impl>>("DefaultFileSource", assetFileSource, cachePath, maximumCacheSize)) { + , impl(std::make_unique<util::Thread<Impl>>("DefaultFileSource", assetFileSource, cachePath)) { } DefaultFileSource::~DefaultFileSource() = default; @@ -351,6 +351,10 @@ void DefaultFileSource::clearAmbientCache(std::function<void (std::exception_ptr impl->actor().invoke(&Impl::clearAmbientCache, std::move(callback)); } +void DefaultFileSource::setMaximumAmbientCacheSize(uint64_t size, std::function<void (std::exception_ptr)> callback) { + impl->actor().invoke(&Impl::setMaximumAmbientCacheSize, size, std::move(callback)); +} + // For testing only: void DefaultFileSource::setOnlineStatus(const bool status) { diff --git a/platform/default/src/mbgl/storage/offline_database.cpp b/platform/default/src/mbgl/storage/offline_database.cpp index 7caa013f9f..24ad3e8432 100644 --- a/platform/default/src/mbgl/storage/offline_database.cpp +++ b/platform/default/src/mbgl/storage/offline_database.cpp @@ -13,9 +13,8 @@ namespace mbgl { -OfflineDatabase::OfflineDatabase(std::string path_, uint64_t maximumCacheSize_) - : path(std::move(path_)), - maximumCacheSize(maximumCacheSize_) { +OfflineDatabase::OfflineDatabase(std::string path_) + : path(std::move(path_)) { try { initialize(); } catch (const util::IOException& ex) { @@ -88,6 +87,19 @@ void OfflineDatabase::cleanup() { } } +bool OfflineDatabase::disabled() { + if (maximumAmbientCacheSize) { + return false; + } + + auto regions = listRegions(); + if (regions && !regions.value().empty()) { + return false; + } + + return true; +} + void OfflineDatabase::handleError(const mapbox::sqlite::Exception& ex, const char* action) { if (ex.code == mapbox::sqlite::ResultCode::NotADB || ex.code == mapbox::sqlite::ResultCode::Corrupt || @@ -177,6 +189,10 @@ mapbox::sqlite::Statement& OfflineDatabase::getStatement(const char* sql) { } optional<Response> OfflineDatabase::get(const Resource& resource) try { + if (disabled()) { + return nullopt; + } + auto result = getInternal(resource); return result ? optional<Response>{ result->first } : nullopt; } catch (const util::IOException& ex) { @@ -209,6 +225,11 @@ std::pair<bool, uint64_t> OfflineDatabase::put(const Resource& resource, const R if (!db) { initialize(); } + + if (disabled()) { + return { false, 0 }; + } + mapbox::sqlite::Transaction transaction(*db, mapbox::sqlite::Transaction::Immediate); auto result = putInternal(resource, response, true); transaction.commit(); @@ -1120,7 +1141,7 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { // The addition of pageSize is a fudge factor to account for non `data` column // size, and because pages can get fragmented on the database. - while (usedSize() + neededFreeSize + pageSize > maximumCacheSize) { + while (usedSize() + neededFreeSize + pageSize > maximumAmbientCacheSize) { // clang-format off mapbox::sqlite::Query accessedQuery{ getStatement( "SELECT max(accessed) " @@ -1187,6 +1208,29 @@ bool OfflineDatabase::evict(uint64_t neededFreeSize) { return true; } +std::exception_ptr OfflineDatabase::setMaximumAmbientCacheSize(uint64_t size) { + uint64_t previousMaximumAmbientCacheSize = maximumAmbientCacheSize; + + try { + maximumAmbientCacheSize = size; + + uint64_t databaseSize = getPragma<int64_t>("PRAGMA page_size") + * getPragma<int64_t>("PRAGMA page_count"); + + if (databaseSize > maximumAmbientCacheSize) { + evict(0); + db->exec("VACUUM"); + } + + return nullptr; + } catch (const mapbox::sqlite::Exception& ex) { + maximumAmbientCacheSize = previousMaximumAmbientCacheSize; + handleError(ex, "set maximum ambient cache size"); + + return std::current_exception(); + } +} + void OfflineDatabase::setOfflineMapboxTileCountLimit(uint64_t limit) { offlineMapboxTileCountLimit = limit; } |