summaryrefslogtreecommitdiff
path: root/platform/default/mbgl/storage
diff options
context:
space:
mode:
Diffstat (limited to 'platform/default/mbgl/storage')
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp73
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp2
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp18
3 files changed, 65 insertions, 28 deletions
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 65c2097182..d7022f1c80 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -1,10 +1,10 @@
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/util/compression.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/logging.hpp>
+#include <mbgl/util/compression.hpp>
#include "sqlite3.hpp"
@@ -153,7 +153,7 @@ optional<Response> OfflineDatabase::get(const Resource& resource) {
optional<std::pair<Response, uint64_t>> OfflineDatabase::getInternal(const Resource& resource) {
if (resource.kind == Resource::Kind::Tile) {
assert(resource.tileData);
- return getTile(*resource.tileData);
+ return getTile(resource);
} else {
return getResource(resource);
}
@@ -177,14 +177,31 @@ std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource,
return { false, 0 };
}
- std::string compressedData;
+ std::shared_ptr<const std::string> data;
bool compressed = false;
uint64_t size = 0;
if (response.data) {
- compressedData = util::compress(*response.data);
- compressed = compressedData.size() < response.data->size();
- size = compressed ? compressedData.size() : response.data->size();
+ if (response.data.isCompressed()) {
+ // The response is already compressed; don't try to compare it against the uncompressed size.
+ compressed = true;
+ data = response.data.compressedData();
+ } else {
+ data = response.data.uncompressedData();
+
+ // Only try to compress the data when we have a good chance that the data can actually
+ // be considerably compressed.
+ if (util::isCompressible(*data)) {
+ const auto compressedData = response.data.compressedData();
+ if (compressedData->size() < data->size()) {
+ compressed = true;
+ data = compressedData;
+ }
+ }
+ }
+ size = data->size();
+ } else {
+ data = std::make_shared<const std::string>();
}
if (evict_ && !evict(size)) {
@@ -196,13 +213,9 @@ std::pair<bool, uint64_t> OfflineDatabase::putInternal(const Resource& resource,
if (resource.kind == Resource::Kind::Tile) {
assert(resource.tileData);
- inserted = putTile(*resource.tileData, response,
- compressed ? compressedData : response.data ? *response.data : "",
- compressed);
+ inserted = putTile(*resource.tileData, response, *data, compressed);
} else {
- inserted = putResource(resource, response,
- compressed ? compressedData : response.data ? *response.data : "",
- compressed);
+ inserted = putResource(resource, response, *data, compressed);
}
return { inserted, size };
@@ -243,12 +256,20 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getResource(const Resou
optional<std::string> data = stmt->get<optional<std::string>>(4);
if (!data) {
response.noContent = true;
- } else if (stmt->get<bool>(5)) {
- response.data = std::make_shared<std::string>(util::decompress(*data));
- size = data->length();
} else {
- response.data = std::make_shared<std::string>(*data);
+ response.data = { std::move(*data), stmt->get<bool>(5) };
size = data->length();
+
+ // Make sure the data is decompressed when the user explicitly requested uncompressed data.
+ if (response.data.isCompressed() &&
+ resource.compression == Resource::Compression::Uncompressed) {
+ try {
+ response.data.uncompress();
+ } catch (std::exception& ex) {
+ response.error =
+ std::make_unique<Response::Error>(Response::Error::Reason::Other, ex.what());
+ }
+ }
}
return std::make_pair(response, size);
@@ -359,7 +380,9 @@ bool OfflineDatabase::putResource(const Resource& resource,
return true;
}
-optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource::TileData& tile) {
+optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource& resource) {
+ const auto& tile = *resource.tileData;
+
// clang-format off
Statement accessedStmt = getStatement(
"UPDATE tiles "
@@ -412,12 +435,20 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource:
optional<std::string> data = stmt->get<optional<std::string>>(4);
if (!data) {
response.noContent = true;
- } else if (stmt->get<bool>(5)) {
- response.data = std::make_shared<std::string>(util::decompress(*data));
- size = data->length();
} else {
- response.data = std::make_shared<std::string>(*data);
+ response.data = { std::move(*data), stmt->get<bool>(5) };
size = data->length();
+
+ // Make sure the data is decompressed when the user explicitly requested uncompressed data.
+ if (response.data.isCompressed() &&
+ resource.compression == Resource::Compression::Uncompressed) {
+ try {
+ response.data.uncompress();
+ } catch (std::exception& ex) {
+ response.error =
+ std::make_unique<Response::Error>(Response::Error::Reason::Other, ex.what());
+ }
+ }
}
return std::make_pair(response, size);
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index 91b544a9e0..fba1a3c230 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -81,7 +81,7 @@ private:
Statement getStatement(const char *);
- optional<std::pair<Response, uint64_t>> getTile(const Resource::TileData&);
+ optional<std::pair<Response, uint64_t>> getTile(const Resource&);
optional<int64_t> hasTile(const Resource::TileData&);
bool putTile(const Resource::TileData&, const Response&,
const std::string&, bool compressed);
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index ba504c1f9b..d8fe8c646b 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -71,7 +71,7 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
}
style::Parser parser;
- parser.parse(*styleResponse->data);
+ parser.parse(*styleResponse->data.uncompressedData());
result.requiredResourceCountIsPrecise = true;
@@ -88,7 +88,8 @@ OfflineRegionStatus OfflineDownload::getStatus() const {
optional<Response> sourceResponse = offlineDatabase.get(Resource::source(url));
if (sourceResponse) {
style::conversion::Error error;
- optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(*sourceResponse->data, error);
+ optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(
+ *sourceResponse->data.uncompressedData(), error);
if (tileset) {
result.requiredResourceCount +=
definition.tileCount(type, tileSize, (*tileset).zoomRange);
@@ -160,7 +161,7 @@ void OfflineDownload::activateDownload() {
status.requiredResourceCountIsPrecise = true;
style::Parser parser;
- parser.parse(*styleResponse.data);
+ parser.parse(*styleResponse.data.uncompressedData());
for (const auto& source : parser.sources) {
SourceType type = source->getType();
@@ -176,7 +177,8 @@ void OfflineDownload::activateDownload() {
ensureResource(Resource::source(url), [=](Response sourceResponse) {
style::conversion::Error error;
- optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(*sourceResponse.data, error);
+ optional<Tileset> tileset = style::conversion::convertJSON<Tileset>(
+ *sourceResponse.data.uncompressedData(), error);
if (tileset) {
util::mapbox::canonicalizeTileset(*tileset, url, type, tileSize);
queueTiles(type, tileSize, *tileset);
@@ -236,14 +238,18 @@ void OfflineDownload::activateDownload() {
if (!parser.glyphURL.empty()) {
for (const auto& fontStack : parser.fontStacks()) {
for (char16_t i = 0; i < GLYPH_RANGES_PER_FONT_STACK; i++) {
- queueResource(Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * GLYPHS_PER_GLYPH_RANGE)));
+ auto resource = Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * GLYPHS_PER_GLYPH_RANGE));
+ resource.compression = Resource::Compression::PreferCompressed;
+ queueResource(resource);
}
}
}
if (!parser.spriteURL.empty()) {
queueResource(Resource::spriteImage(parser.spriteURL, definition.pixelRatio));
- queueResource(Resource::spriteJSON(parser.spriteURL, definition.pixelRatio));
+ auto spriteJSON = Resource::spriteJSON(parser.spriteURL, definition.pixelRatio);
+ spriteJSON.compression = Resource::Compression::PreferCompressed;
+ queueResource(spriteJSON);
}
continueDownload();