diff options
Diffstat (limited to 'platform/default/src/mbgl/storage')
-rw-r--r-- | platform/default/src/mbgl/storage/default_file_source.cpp | 24 | ||||
-rw-r--r-- | platform/default/src/mbgl/storage/offline_database.cpp | 52 |
2 files changed, 62 insertions, 14 deletions
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; } |